11from typing import Union
2+ from typing import Optional
23
34from qtpy .QtCore import Qt
45from qtpy .QtCore import QUrl
@@ -312,6 +313,32 @@ def make_button(
312313 return btn
313314
314315
316+ class DropdownMenu (QComboBox ):
317+ """Creates a dropdown menu with a title and adds specified entries to it"""
318+
319+ def __init__ (
320+ self ,
321+ entries : Optional [list ] = None ,
322+ parent : Optional [QWidget ] = None ,
323+ label : Optional [str ] = None ,
324+ fixed : Optional [bool ] = True ,
325+ ):
326+ """Args:
327+ entries (array(str)): Entries to add to the dropdown menu. Defaults to None, no entries if None
328+ parent (QWidget): parent QWidget to add dropdown menu to. Defaults to None, no parent is set if None
329+ label (str) : if not None, creates a QLabel with the contents of 'label', and returns the label as well
330+ fixed (bool): if True, will set the size policy of the dropdown menu to Fixed in h and w. Defaults to True.
331+ """
332+ super ().__init__ (parent )
333+ self .label = None
334+ if entries is not None :
335+ self .addItems (entries )
336+ if label is not None :
337+ self .label = QLabel (label )
338+ if fixed :
339+ self .setSizePolicy (QSizePolicy .Fixed , QSizePolicy .Fixed )
340+
341+
315342def make_combobox (
316343 entries = None ,
317344 parent : QWidget = None ,
@@ -329,22 +356,13 @@ def make_combobox(
329356 Returns:
330357 QComboBox : created dropdown menu
331358 """
332- if parent is None :
333- menu = QComboBox ()
334- else :
335- menu = QComboBox (parent )
336-
337- if entries is not None :
338- menu .addItems (entries )
339-
340- if fixed :
341- menu .setSizePolicy (QSizePolicy .Fixed , QSizePolicy .Fixed )
342-
343359 if label is not None :
344- label = QLabel (label )
360+ menu = DropdownMenu (entries , parent , label , fixed )
361+ label = menu .label
345362 return menu , label
346-
347- return menu
363+ else :
364+ menu = DropdownMenu (entries , parent , fixed = fixed )
365+ return menu
348366
349367
350368def add_widgets (layout , widgets , alignment = LEFT_AL ):
@@ -363,6 +381,30 @@ def add_widgets(layout, widgets, alignment=LEFT_AL):
363381 layout .addWidget (w , alignment = alignment )
364382
365383
384+ class CheckBox (QCheckBox ):
385+ """Shortcut for creating QCheckBox with a title and a function"""
386+
387+ def __init__ (
388+ self ,
389+ title : Optional [str ] = None ,
390+ func : Optional [callable ] = None ,
391+ parent : Optional [QWidget ] = None ,
392+ fixed : Optional [bool ] = True ,
393+ ):
394+ """
395+ Args:
396+ title (str-like): title of the checkbox. Defaults to None, if None no title is set
397+ func (callable): function to execute when checkbox is toggled. Defaults to None, no binding is made if None
398+ parent (QWidget): parent QWidget to add checkbox to. Defaults to None, no parent is set if None
399+ fixed (bool): if True, will set the size policy of the checkbox to Fixed in h and w. Defaults to True.
400+ """
401+ super ().__init__ (title , parent )
402+ if fixed :
403+ self .setSizePolicy (QSizePolicy .Fixed , QSizePolicy .Fixed )
404+ if func is not None :
405+ self .toggled .connect (func )
406+
407+
366408def make_checkbox (
367409 title : str = None ,
368410 func : callable = None ,
@@ -378,26 +420,10 @@ def make_checkbox(
378420 fixed (bool): if True, will set the size policy of the checkbox to Fixed in h and w. Defaults to True.
379421
380422 Returns:
381- QCheckBox : created button
423+ QCheckBox : created widget
382424 """
383- if parent is not None :
384- if title is not None :
385- box = QCheckBox (title , parent )
386- else :
387- box = QCheckBox (parent )
388- else :
389- if title is not None :
390- box = QCheckBox (title , parent )
391- else :
392- box = QCheckBox (parent )
393425
394- if fixed :
395- box .setSizePolicy (QSizePolicy .Fixed , QSizePolicy .Fixed )
396-
397- if func is not None :
398- box .toggled .connect (func )
399-
400- return box
426+ return CheckBox (title , func , parent , fixed )
401427
402428
403429def combine_blocks (
@@ -456,6 +482,76 @@ def combine_blocks(
456482 return temp_widget
457483
458484
485+ def toggle_visibility (checkbox , widget ):
486+ """Toggles the visibility of a widget based on the status of a checkbox.
487+
488+ Args:
489+ checkbox: The QCheckbox that determines whether to show or not
490+ widget: The widget to hide or show
491+ """
492+ widget .setVisible (checkbox .isChecked ())
493+
494+
495+ class AnisotropyWidgets (QWidget ):
496+ def __init__ (self , parent , default_x = 1 , default_y = 1 , default_z = 1 ):
497+ super ().__init__ (parent )
498+
499+ self ._layout = QVBoxLayout ()
500+ self ._layout .setSpacing (0 )
501+ self ._layout .setContentsMargins (0 , 0 , 0 , 0 )
502+
503+ self .container , self ._boxes_layout = make_container (T = 7 , parent = parent )
504+ self .checkbox = make_checkbox (
505+ "Anisotropic data" , self .toggle_display_aniso , parent
506+ )
507+
508+ self .box_widgets = make_n_spinboxes (
509+ n = 3 , min = 1.0 , max = 1000 , default = 1 , step = 0.5 , double = True
510+ )
511+ self .box_widgets [0 ].setValue (default_x ) # TODO change default
512+ self .box_widgets [1 ].setValue (default_y ) # TODO change default
513+ self .box_widgets [2 ].setValue (default_z ) # TODO change default
514+
515+ for w in self .box_widgets :
516+ w .setSizePolicy (QSizePolicy .Fixed , QSizePolicy .Fixed )
517+
518+ self .box_widgets_lbl = [
519+ make_label ("Resolution in " + axis + " (microns) :" , parent = parent )
520+ for axis in "xyz"
521+ ]
522+
523+ ##################
524+ # tooltips
525+ self .checkbox .setToolTip (
526+ "If you have anisotropic data, you can scale data using your resolution in microns"
527+ )
528+ [w .setToolTip ("Resolution in microns" ) for w in self .box_widgets ]
529+ ##################
530+
531+ self .build ()
532+
533+ def toggle_display_aniso (self ):
534+ """Shows the choices for correcting anisotropy when viewing results depending on whether :py:attr:`self.checkbox` is checked"""
535+ toggle_visibility (self .checkbox , self .container )
536+
537+ def build (self ):
538+ [
539+ self ._boxes_layout .addWidget (widget , alignment = LEFT_AL )
540+ for widgets in zip (self .box_widgets_lbl , self .box_widgets )
541+ for widget in widgets
542+ ]
543+ # anisotropy
544+ self .container .setLayout (self ._boxes_layout )
545+ self .container .setVisible (False )
546+
547+ add_widgets (self ._layout , [self .checkbox , self .container ])
548+ self .setLayout (self ._layout )
549+
550+ def get_anisotropy_factors (self ):
551+ """Returns : the resolution in microns for each of the three dimensions"""
552+ return [w .value () for w in self .box_widgets ]
553+
554+
459555def open_url (url ):
460556 """Opens the url given as a string in OS default browser using :py:func:`QDesktopServices.openUrl`.
461557
0 commit comments