diff --git a/Orange/widgets/visualize/tests/test_vizrankdialog.py b/Orange/widgets/visualize/tests/test_vizrankdialog.py index fb3f11f9889..343bb6e41ca 100644 --- a/Orange/widgets/visualize/tests/test_vizrankdialog.py +++ b/Orange/widgets/visualize/tests/test_vizrankdialog.py @@ -41,7 +41,7 @@ def test_run_vizrank(self): res_scores = sorted([compute_score(x) for x in states]) self.assertListEqual(res.scores, res_scores) self.assertIsNot(scores, res.scores) - self.assertEqual(task.set_partial_result.call_count, 6) + self.assertEqual(task.set_partial_result.call_count, 2) self.assertEqual(task.set_progress_value.call_count, 7) def test_run_vizrank_interrupt(self): @@ -59,7 +59,7 @@ def test_run_vizrank_interrupt(self): res_scores = sorted([compute_score(x) for x in states[:2]]) self.assertListEqual(res.scores, res_scores) self.assertIsNot(scores, res.scores) - self.assertEqual(task.set_partial_result.call_count, 2) + self.assertEqual(task.set_partial_result.call_count, 1) self.assertEqual(task.set_progress_value.call_count, 3) task.set_progress_value.assert_called_with(int(1 / 6 * 100)) @@ -76,7 +76,7 @@ def test_run_vizrank_interrupt(self): res_scores = sorted([compute_score(x) for x in states]) self.assertListEqual(res.scores, res_scores) self.assertIsNot(scores, res.scores) - self.assertEqual(task.set_partial_result.call_count, 6) + self.assertEqual(task.set_partial_result.call_count, 3) self.assertEqual(task.set_progress_value.call_count, 8) task.set_progress_value.assert_called_with(int(5 / 6 * 100)) diff --git a/Orange/widgets/visualize/utils/__init__.py b/Orange/widgets/visualize/utils/__init__.py index 99c0b6c5f94..4d03d73f4c2 100644 --- a/Orange/widgets/visualize/utils/__init__.py +++ b/Orange/widgets/visualize/utils/__init__.py @@ -7,6 +7,7 @@ from queue import Queue, Empty from types import SimpleNamespace as namespace from typing import Optional, Iterable, List, Callable +from threading import Timer from AnyQt.QtCore import Qt, QSize, pyqtSignal as Signal, QSortFilterProxyModel from AnyQt.QtGui import QStandardItemModel, QStandardItem, QColor, QBrush, QPen @@ -393,6 +394,7 @@ def run_vizrank(compute_score: Callable, iterate_states: Callable, task.set_status("Getting scores...") res = Result(queue=Queue(), scores=None) scores = scores.copy() + can_set_partial_result = True def do_work(st, next_st): try: @@ -405,7 +407,10 @@ def do_work(st, next_st): except Exception: # ignore current state in case of any problem pass res.scores = scores.copy() - task.set_partial_result(res) + + def reset_flag(): + nonlocal can_set_partial_result + can_set_partial_result = True state = None next_state = next(states) @@ -419,8 +424,18 @@ def do_work(st, next_st): state = copy.copy(next_state) next_state = copy.copy(next(states)) do_work(state, next_state) + # for simple scores (e.g. correlations widget) and many feature + # combinations, the 'partial_result_ready' signal (emitted by + # invoking 'task.set_partial_result') was emitted too frequently + # for a longer period of time and therefore causing the widget + # being unresponsive + if can_set_partial_result: + task.set_partial_result(res) + can_set_partial_result = False + Timer(0.01, reset_flag).start() except StopIteration: do_work(state, None) + task.set_partial_result(res) return res