26
26
from functools import partial
27
27
28
28
#PyQt
29
- from PyQt5 .QtCore import pyqtSignal , Qt , QPointF , QSize , QTimer
29
+ from PyQt5 .QtCore import pyqtSignal , Qt , QPointF , QPoint , QRect , QSize
30
30
from PyQt5 .QtGui import QPen , QPainter , QPixmap , QColor , QFont , QPainterPath , QBrush , QTransform , QIcon
31
31
32
32
from PyQt5 .QtWidgets import (
41
41
QSizePolicy ,
42
42
QSlider ,
43
43
QToolButton ,
44
+ QLineEdit
44
45
)
45
46
46
47
@@ -416,53 +417,16 @@ def setAxes(self, rotation, swapped):
416
417
self .buttons ["swap-axes" ].swapped = swapped
417
418
418
419
419
- def _get_pos_widget (name , backgroundColor , foregroundColor ):
420
- label = QLabel ()
421
- label .setAttribute (Qt .WA_TransparentForMouseEvents , True )
422
-
423
- pixmap = QPixmap (25 * 10 , 25 * 10 )
424
- pixmap .fill (backgroundColor )
425
- painter = QPainter ()
426
- painter .begin (pixmap )
427
- pen = QPen (foregroundColor )
428
- painter .setPen (pen )
429
- painter .setRenderHint (QPainter .Antialiasing )
430
- font = QFont ()
431
- font .setBold (True )
432
- font .setPixelSize (25 * 10 - 30 )
433
- path = QPainterPath ()
434
- path .addText (QPointF (50 , 25 * 10 - 50 ), font , name )
435
- brush = QBrush (foregroundColor )
436
- painter .setBrush (brush )
437
- painter .drawPath (path )
438
- painter .setFont (font )
439
- painter .end ()
440
- pixmap = pixmap .scaled (QSize (20 , 20 ), Qt .KeepAspectRatio , Qt .SmoothTransformation )
441
- label .setPixmap (pixmap )
442
-
443
- spinbox = DelayedSpinBox (750 )
444
- spinbox .setAlignment (Qt .AlignCenter )
445
- spinbox .setToolTip ("{0} Spin Box" .format (name ))
446
- spinbox .setButtonSymbols (QAbstractSpinBox .NoButtons )
447
- spinbox .setMaximumHeight (20 )
448
- font = spinbox .font ()
449
- font .setPixelSize (14 )
450
- spinbox .setFont (font )
451
- sheet = TEMPLATE .format (foregroundColor .name (), backgroundColor .name ())
452
- spinbox .setStyleSheet (sheet )
453
- return label , spinbox
454
-
455
-
456
420
class QuadStatusBar (QHBoxLayout ):
457
421
458
- positionChanged = pyqtSignal (int , int , int ) # x,y,z
459
-
460
- def __init__ (self , parent = None ):
422
+ positionChanged = pyqtSignal (int , int , int ) # x,y,z
423
+
424
+ def __init__ (self , volumeEditor , parent = None ):
461
425
QHBoxLayout .__init__ (self , parent )
462
426
self .setContentsMargins (0 , 4 , 0 , 0 )
463
427
self .setSpacing (0 )
464
428
self .timeControlFontSize = 12
465
- self .layerStack = layerStack
429
+ self .editor = volumeEditor
466
430
467
431
def showXYCoordinates (self ):
468
432
self .zLabel .setHidden (True )
@@ -491,11 +455,14 @@ def setToolTipTimeSlider(self, croppingFlag=False):
491
455
self .timeSlider .setToolTip ("Choose the time coordinate of the current dataset." )
492
456
493
457
def createQuadViewStatusBar (
494
- self , xbackgroundColor , xforegroundColor , ybackgroundColor , yforegroundColor , zbackgroundColor , zforegroundColor
458
+ self , xbackgroundColor , xforegroundColor , ybackgroundColor , yforegroundColor , zbackgroundColor ,
459
+ zforegroundColor , labelbackgroundColor , labelforegroundColor
495
460
):
496
- self .xLabel , self .xSpinBox = _get_pos_widget ("X" , xbackgroundColor , xforegroundColor )
497
- self .yLabel , self .ySpinBox = _get_pos_widget ("Y" , ybackgroundColor , yforegroundColor )
498
- self .zLabel , self .zSpinBox = _get_pos_widget ("Z" , zbackgroundColor , zforegroundColor )
461
+ self .xLabel , self .xSpinBox = self ._get_pos_widget ("X" , xbackgroundColor , xforegroundColor )
462
+ self .yLabel , self .ySpinBox = self ._get_pos_widget ("Y" , ybackgroundColor , yforegroundColor )
463
+ self .zLabel , self .zSpinBox = self ._get_pos_widget ("Z" , zbackgroundColor , zforegroundColor )
464
+ self .labelWidget = self ._get_posMeta_widget (labelbackgroundColor , labelforegroundColor )
465
+ self .labelbackgroundColor = labelbackgroundColor
499
466
500
467
self .xSpinBox .delayedValueChanged .connect (partial (self ._handlePositionBoxValueChanged , "x" ))
501
468
self .ySpinBox .delayedValueChanged .connect (partial (self ._handlePositionBoxValueChanged , "y" ))
@@ -624,10 +591,7 @@ def _get_pos_widget(self, name, backgroundColor, foregroundColor):
624
591
spinbox .setStyleSheet (sheet )
625
592
return label , spinbox
626
593
627
- def _get_label_widget (self , backgroundColor , foregroundColor ):
628
- ticker = QTimer ()
629
- ticker .setInterval (200 )
630
- ticker .setSingleShot (True )
594
+ def _get_posMeta_widget (self , backgroundColor , foregroundColor ):
631
595
ledit = QLineEdit ()
632
596
ledit .setAlignment (Qt .AlignCenter )
633
597
ledit .setMaximumHeight (20 )
@@ -641,58 +605,39 @@ def _get_label_widget(self, backgroundColor, foregroundColor):
641
605
f"background-color: { backgroundColor .name ()} ;"
642
606
f"border: none" )
643
607
644
- return ledit , ticker
608
+ return ledit
645
609
646
- def _set_label_widget (self , x , y , z , t ):
610
+ def _set_posMeta_widget (self , x , y , z ):
647
611
"""Updates the label widget according to current mouse cursor position (x,y,z) and selectet time frame (t)"""
648
- # from lazyflow.roi import TinyVector
649
- # from collections import namedtuple
650
-
651
- # no need for the color dimension (last element) here.
652
- slicing = [slice (int (i ), int (i + 1 )) for i in [t , x , y , z ]] + [slice (0 ,1 )]
653
- # Roi = namedtuple('Roi', 'start stop')
654
- # roi = Roi(start=TinyVector([int(t),int(y),int(x),int(z)]), stop=TinyVector([int(t+1),int(y+1),int(x+1),int(z+1)]))
655
612
label = None
613
+ coords = [int (val ) for val in [x ,y ,z ]]
614
+ imgView = self .editor .posModel .activeView
615
+ blockSize = self .editor .imageViews [imgView ].scene ()._tileProvider .tiling .blockSize
616
+ del coords [imgView ]
617
+ x ,y = (val for val in coords )
618
+ if imgView == 0 :
619
+ x ,y = (y ,x )
656
620
try :
657
- def findLayer (layer ):
658
- if "Segmentation (Label " in layer .name :
659
- return True
660
- labelings = self .layerStack .findMatchingIndices (findLayer ) # this throws exception if no layer found
661
- for lbl in labelings :
662
- try :
663
- fixed = []
664
- # FIXME This is really hacky, need to find another way of retrieving the cached values without the cache blocking the request
665
- for op in self .layerStack [lbl ].datasources [0 ].dataSlot .getRealOperator ().opPredictionPipeline .innerOperators [0 ].prediction_cache_gui ._innerOps :
666
- fixed .append (op ._opCacheFixer ._fixed )
667
- op ._opCacheFixer ._fixed = False
668
-
669
- # Get the whole dataset (debugging purposes)
670
- # whole_set_roi = Roi(start=TinyVector([0, 0, 0, 0]),
671
- # whole_set_slicing = [slice(int(0), int(i)) for i in [2, 1343, 1022, 1]] + [slice(0,1)]
672
- # set_fromRoi = self.layerStack[lbl].datasources[0].dataSlot.get(whole_set_roi).wait()
673
- # set_fromSlice = self.layerStack[lbl].datasources[0].request(whole_set_slicing).wait()
674
- # set_fromVal = self.layerStack[lbl].datasources[0].dataSlot.value
675
-
676
- # Equivalent calls to opCacheFixer
677
- # val = self.layerStack[lbl].datasources[0].dataSlot.get(roi).wait()
678
- # val = self.layerStack[lbl].datasources[0].dataSlot(roi.start, roi.stop).wait()
679
- val = self .layerStack [lbl ].datasources [0 ].request (slicing ).wait ()
680
-
681
- # This does not call cached values, hence no need to hack the cache. But it is way to slow
682
- # val = self.layerStack[lbl].datasources[0].dataSlot.value[int(t),int(y),int(x),int(z)]
683
- finally :
684
- if fixed :
685
- for fx , op in zip (fixed , self .layerStack [lbl ].datasources [0 ].dataSlot .getRealOperator ().opPredictionPipeline .innerOperators [0 ].prediction_cache_gui ._innerOps ):
686
- op ._opCacheFixer ._fixed = fx
687
- if val == 1 : # indicates, that 'sclicing' is labelled with the label 'lbl'
688
- name = self .layerStack [lbl ].name
689
- label = name [name .find ("(" ) + 1 :name .find (")" )]
690
- color = self .layerStack [lbl ].tintColor .name ()
691
- self .labelWidget .setStyleSheet (f"color: white;"
692
- f"background-color: { color } ;"
693
- f"border: none" )
694
- self .labelWidget .setText (f"{ label } " )
695
- break
621
+ for layer in self .editor .layerStack :
622
+ if layer .visible :
623
+ layer_id = self .editor .imagepumps [imgView ].stackedImageSources ._layerToIms [layer ]
624
+ stack_id = self .editor .imageViews [imgView ].scene ()._tileProvider ._current_stack_id
625
+ tile_id = self .editor .imageViews [imgView ].scene ()._tileProvider .tiling .intersected (QRect (QPoint (x ,y ), QPoint (x ,y )))[0 ] # There will be just one tile, since we have just a single point
626
+
627
+ with self .editor .imageViews [imgView ].scene ()._tileProvider ._cache :
628
+ image = self .editor .imageViews [imgView ].scene ()._tileProvider ._cache .layer (stack_id , layer_id ,
629
+ tile_id )
630
+ if image is not None :
631
+ colorVal = image .pixelColor (x % blockSize ,y % blockSize )
632
+ if "Segmentation (Label " in layer .name and colorVal .getRgb () != (0 ,0 ,0 ,0 ):
633
+ name = layer .name
634
+ label = name [name .find ("(" ) + 1 :name .find (")" )]
635
+ color = layer .tintColor .name ()
636
+ self .labelWidget .setStyleSheet (f"color: white;"
637
+ f"background-color: { color } ;"
638
+ f"border: none" )
639
+ self .labelWidget .setText (f"{ label } " )
640
+ break
696
641
if label is None :
697
642
raise ValueError ("No matching layer in stack." )
698
643
except ValueError as e :
@@ -703,6 +648,8 @@ def findLayer(layer):
703
648
704
649
if str (e ) != "No matching layer in stack." :
705
650
raise
651
+ except :
652
+ raise
706
653
707
654
def _registerTimeframeShortcuts (self , enabled = True , remove = True ):
708
655
""" Register or deregister "," and "." as keyboard shortcuts for scrolling in time """
@@ -817,13 +764,11 @@ def updateShape5Dcropped(self, shape5DcropMin, shape5Dmax):
817
764
self .zSpinBox .setValue (shape5DcropMin [3 ])
818
765
self .timeSlider .setValue (shape5DcropMin [0 ])
819
766
820
- def setMouseCoords (self , x , y , z , t ):
767
+ def setMouseCoords (self , x , y , z ):
821
768
self .xSpinBox .setValueWithoutSignal (x )
822
769
self .ySpinBox .setValueWithoutSignal (y )
823
770
self .zSpinBox .setValueWithoutSignal (z )
824
- if not self .pos_info_ticker .isActive ():
825
- self ._set_label_widget (x , y , z , t )
826
- self .pos_info_ticker .start ()
771
+ self ._set_posMeta_widget (x , y , z )
827
772
828
773
829
774
if __name__ == "__main__" :
0 commit comments