3838from silx .utils .weakref import WeakMethodProxy
3939from silx .gui import icons
4040from silx .gui .plot import PlotWidget
41+ from silx .gui .plot .tools .profile .core import ProfileRoiMixIn
4142from silx .gui .plot .tools .roi import RegionOfInterestManager
4243from silx .gui .plot .tools .roi import CreateRoiModeAction
4344from silx .gui .plot import items
5455class _RunnableComputeProfile (qt .QRunnable ):
5556 """Runner to process profiles
5657
57- :param qt.QThreadPool threadPool: The thread which will be used to
58- execute this runner. It is used to update the used signals
59- :param ~silx.gui.plot.items.Item item: Item in which the profile is
60- computed
61- :param ~silx.gui.plot.tools.profile.core.ProfileRoiMixIn roi: ROI
62- defining the profile shape and other characteristics
58+ :param item: Item in which the profile is computed
59+ :param roi: ROI defining the profile shape and other characteristics
6360 """
6461
65- class _Signals (qt .QObject ):
62+ class Signal (qt .QObject ):
6663 """Signal holder"""
67-
68- resultReady = qt .Signal (object , object )
6964 runnerFinished = qt .Signal (object )
7065
71- def __init__ (self , threadPool , item , roi ):
72- """Constructor"""
66+ def __init__ (self , item : items .Item , roi : ProfileRoiMixIn ):
7367 super (_RunnableComputeProfile , self ).__init__ ()
74- self ._signals = self . _Signals ( )
75- self ._signals . moveToThread ( threadPool . thread () )
68+ self .setAutoDelete ( False )
69+ self ._signal = self . Signal ( )
7670 self ._item = item
7771 self ._roi = roi
78- self ._cancelled = False
79-
80- def _lazyCancel (self ):
81- """Cancel the runner if it is not yet started.
82-
83- The threadpool will still execute the runner, but this will process
84- nothing.
85-
86- This is only used with Qt<5.9 where QThreadPool.tryTake is not available.
87- """
88- self ._cancelled = True
89-
90- def autoDelete (self ):
91- return False
92-
93- def getRoi (self ):
94- """Returns the ROI in which the runner will compute a profile.
95-
96- :rtype: ~silx.gui.plot.tools.profile.core.ProfileRoiMixIn
97- """
98- return self ._roi
99-
100- @property
101- def resultReady (self ):
102- """Signal emitted when the result of the computation is available.
103-
104- This signal provides 2 values: The ROI, and the computation result.
105- """
106- return self ._signals .resultReady
72+ self ._profileData = None
10773
10874 @property
10975 def runnerFinished (self ):
110- """Signal emitted when runner have finished.
76+ return self . _signal . runnerFinished
11177
112- This signal provides a single value: the runner itself.
113- """
114- return self ._signals .runnerFinished
78+ def getRoi (self ) -> ProfileRoiMixIn :
79+ """Returns the ROI in which the runner will compute a profile."""
80+ return self ._roi
81+
82+ def getProfileData (self ):
83+ """Returns result data or None if failure or not finished"""
84+ return self ._profileData
11585
116- def run (self ):
86+ def run (self ) -> None :
11787 """Process the profile computation."""
118- if not self ._cancelled :
119- try :
120- profileData = self ._roi .computeProfile (self ._item )
121- except Exception :
122- _logger .error ("Error while computing profile" , exc_info = True )
123- else :
124- self .resultReady .emit (self ._roi , profileData )
125- self .runnerFinished .emit (self )
88+ try :
89+ self ._profileData = self ._roi .computeProfile (self ._item )
90+ except Exception :
91+ _logger .error ("Error while computing profile" , exc_info = True )
92+ self ._signal .runnerFinished .emit (self )
12693
12794
12895class ProfileWindow (qt .QMainWindow ):
@@ -857,12 +824,8 @@ def requestUpdateProfile(self, profileRoi):
857824 if not inspect .isValid (runner ):
858825 self ._pendingRunners .remove (runner )
859826 continue
860- if runner .getRoi () is profileRoi :
861- if hasattr (threadPool , "tryTake" ):
862- if threadPool .tryTake (runner ):
863- self ._pendingRunners .remove (runner )
864- else : # Support Qt<5.9
865- runner ._lazyCancel ()
827+ if runner .getRoi () is profileRoi and threadPool .tryTake (runner ):
828+ self ._pendingRunners .remove (runner )
866829
867830 item = self .getPlotItem ()
868831 if item is None or not isinstance (item , profileRoi .ITEM_KIND ):
@@ -874,26 +837,21 @@ def requestUpdateProfile(self, profileRoi):
874837 return
875838
876839 profileRoi ._setPlotItem (item )
877- runner = _RunnableComputeProfile (threadPool , item , profileRoi )
878- runner .runnerFinished .connect (self .__cleanUpRunner )
879- runner .resultReady .connect (self .__displayResult )
840+ runner = _RunnableComputeProfile (item , profileRoi )
841+ runner .runnerFinished .connect (self .__runnerFinished )
880842 self ._pendingRunners .append (runner )
881843 threadPool .start (runner )
882844
883- def __cleanUpRunner (self , runner ):
884- """Remove a thread pool runner from the list of hold tasks.
885-
886- Called at the termination of the runner.
887- """
845+ def __runnerFinished (self , runner : _RunnableComputeProfile ):
846+ """Clean-up profile runner and display its result"""
888847 if runner in self ._pendingRunners :
889848 self ._pendingRunners .remove (runner )
890849
891- def __displayResult (self , roi , profileData ):
892- """Display the result of a ROI.
850+ roi = runner .getRoi ()
851+ profileData = runner .getProfileData ()
852+ if profileData is None :
853+ return
893854
894- :param ~core.ProfileRoiMixIn profileRoi: A managed ROI
895- :param ~core.CurveProfileData profileData: Computed data profile
896- """
897855 if roi in self .__reentrantResults :
898856 # Store the data to process it in the main loop
899857 # And not a sub loop created by initProfileWindow
0 commit comments