def connect(cls, controller_widget, control_name, control_instance): """ Connect a 'Bool' controller trait and a 'BoolControlWidget' controller widget control. Parameters ---------- cls: BoolControlWidget (mandatory) a BoolControlWidget control controller_widget: ControllerWidget (mandatory) a controller widget that contains the controller we want to update control_name: str (mandatory) the name of the controller widget control we want to synchronize with the controller control_instance: QCheckBox (mandatory) the instance of the controller widget control we want to synchronize with the controller """ # Check if the control is connected if not control_instance.connected: # Update one element of the controller. # Hook: function that will be called to update a specific # controller trait when a 'textChanged' qt signal is emited widget_hook = partial(cls.update_controller, weak_proxy(controller_widget), control_name, weak_proxy(control_instance)) # When a qt 'clicked' signal is emited, update the # 'control_name' controller trait value control_instance.clicked.connect(widget_hook) # Update the control. # Hook: function that will be called to update the control value # when the 'control_name' controller trait is modified. controller_hook = SomaPartial(cls.update_controller_widget, weak_proxy(controller_widget), control_name, weak_proxy(control_instance)) # When the 'control_name' controller trait value is modified, # update the corresponding control controller_widget.controller.on_trait_change(controller_hook, name=control_name, dispatch='ui') # Store the trait - control connection we just build control_instance._controller_connections = (widget_hook, controller_hook) logger.debug("Add 'String' connection: {0}.".format( control_instance._controller_connections)) # Update the control connection status control_instance.connected = True
def connect(cls, controller_widget, control_name, control_instance): """ Connect an 'Enum' controller trait and an 'EnumControlWidget' controller widget control. Parameters ---------- cls: EnumControlWidget (mandatory) an EnumControlWidget control controller_widget: ControllerWidget (mandatory) a controller widget that contains the controller we want to update control_name: str (mandatory) the name of the controller widget control we want to synchronize with the controller control_instance: QComboBox (mandatory) the instance of the controller widget control we want to synchronize with the controller """ # Update one element of the controller. # Hook: function that will be called to update a specific # controller trait when an 'activated' qt signal is emited widget_hook = partial(cls.update_controller, weak_proxy(controller_widget), control_name, weak_proxy(control_instance)) # When a qt 'activated' signal is emited, update the # 'control_name' controller trait value control_instance.activated.connect(widget_hook) # Update one element of the controller widget. # Hook: function that will be called to update the specific widget # when a trait event is detected. controller_hook = SomaPartial(cls.update_controller_widget, weak_proxy(controller_widget), control_name, weak_proxy(control_instance)) # When the 'control_name' controller trait value is modified, update # the corresponding control controller_widget.controller.on_trait_change(controller_hook, name=control_name, dispatch='ui') # Store the trait - control connection we just build control_instance._controller_connections = (widget_hook, controller_hook) logger.debug("Add 'Enum' connection: {0}.".format( control_instance._controller_connections))
def check(cls, control_instance): """ Check if a controller widget control is filled correctly. Parameters ---------- cls: EnumControlWidget (mandatory) an EnumControlWidget control control_instance: QComboBox (mandatory) the control widget we want to validate """ # Hook: function that will be called to check for typo # when a 'textEdited' qt signal is emited widget_callback = partial(cls.is_valid, weak_proxy(control_instance)) # Execute manually the first time the control check method widget_callback() # When a qt 'editTextChanged' signal is emited, check if the new # user value is correct control_instance.editTextChanged.connect(widget_callback)
def check(cls, control_instance): """ Check if a controller widget control is filled correctly. Parameters ---------- cls: FileControlWidget (mandatory) a StrControlWidget control control_instance: QWidget (mandatory) the control widget we want to validate """ # Hook: function that will be called to check for typo # when a 'userModification' qt signal is emited widget_callback = partial(cls.is_valid, weak_proxy(control_instance)) # The first time execute manually the control check method widget_callback() # When a qt 'userModification' signal is emited, check if the new # user value is correct control_instance.path.userModification.connect(widget_callback)
def connect(cls, controller_widget, control_name, control_instance): """ Connect a 'List' controller trait and a 'DictControlWidget' controller widget control. Parameters ---------- cls: StrControlWidget (mandatory) a StrControlWidget control controller_widget: ControllerWidget (mandatory) a controller widget that contains the controller we want to update control_name: str (mandatory) the name of the controller widget control we want to synchronize with the controller control_instance: QFrame (mandatory) the instance of the controller widget control we want to synchronize with the controller """ # Check if the control is connected if not control_instance.connected: # Update the dict item when one of his associated controller trait # changed. # Hook: function that will be called to update the controller # associated with a dict widget when a dict widget inner controller # trait is modified. dict_controller_hook = SomaPartial( cls.update_controller, weak_proxy(controller_widget), control_name, weak_proxy(control_instance)) # Go through all dict widget inner controller user traits for trait_name in control_instance.controller.user_traits(): # And add the callback on each user trait control_instance.controller.on_trait_change( dict_controller_hook, trait_name) logger.debug("Item '{0}' of a 'DictControlWidget', add " "a callback on inner controller trait " "'{0}'.".format(control_name, trait_name)) # Update the dict controller widget. # Hook: function that will be called to update the specific widget # when a trait event is detected on the dict controller. controller_hook = SomaPartial( cls.update_controller_widget, weak_proxy(controller_widget), control_name, weak_proxy(control_instance)) # When the 'control_name' controller trait value is modified, # update the corresponding control controller_widget.controller.on_trait_change( controller_hook, control_name, dispatch='ui') # Update the dict connection status control_instance._controller_connections = ( dict_controller_hook, controller_hook) logger.debug("Add 'Dict' connection: {0}.".format( control_instance._controller_connections)) # Connect also all dict items inner_controls = control_instance.controller_widget._controls for (inner_control_name, inner_control_groups) in six.iteritems(inner_controls): for group, inner_control \ in six.iteritems(inner_control_groups): # Unpack the control item inner_control_instance = inner_control[2] inner_control_class = inner_control[1] # Call the inner control connect method inner_control_class.connect( control_instance.controller_widget, inner_control_name, inner_control_instance) # Update the dict control connection status control_instance.connected = True
def create_widget(parent, control_name, control_value, trait, label_class=None): """ Method to create the dict widget. Parameters ---------- parent: QWidget (mandatory) the parent widget control_name: str (mandatory) the name of the control we want to create control_value: dict of items (mandatory) the default control value trait: Tait (mandatory) the trait associated to the control label_class: Qt widget class (optional, default: None) the label widget will be an instance of this class. Its constructor will be called using 2 arguments: the label string and the parent widget. Returns ------- out: 2-uplet a two element tuple of the form (control widget: , associated labels: (a label QLabel, the tools QWidget)) """ # Get the inner trait: expect only one inner trait # note: trait.inner_traits might be a method (ListInt) or a tuple # (List), whereas trait.handler.inner_trait is always a method if len(trait.handler.inner_traits()) != 2: raise Exception( "Expect two inner traits in Dict control. Trait '{0}' " "inner traits are '{1}'.".format( control_name, trait.inner_traits)) inner_trait = trait.handler.inner_traits()[1] # Create the dict widget: a frame frame = QtGui.QFrame(parent=parent) frame.setFrameShape(QtGui.QFrame.StyledPanel) # Create tools to interact with the dict widget: expand or collapse - # add a dict item - remove a dict item tool_widget = QtGui.QWidget(parent) layout = QtGui.QHBoxLayout() layout.addStretch(1) tool_widget.setLayout(layout) # Create the tool buttons resize_button = QtGui.QToolButton() add_button = QtGui.QToolButton() layout.addWidget(resize_button) layout.addWidget(add_button) # Set the tool icons icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/add")), QtGui.QIcon.Normal, QtGui.QIcon.Off) add_button.setIcon(icon) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_down")), QtGui.QIcon.Normal, QtGui.QIcon.Off) resize_button.setIcon(icon) resize_button.setFixedSize(30, 22) add_button.setFixedSize(30, 22) # Create a new controller that contains length 'control_value' inner # trait elements controller = DictController() for name, inner_control_values in six.iteritems(control_value): controller.add_trait(str(name), inner_trait) setattr(controller, str(name), inner_control_values) # Create the associated controller widget controller_widget = ControllerWidget(controller, parent=frame, live=True, editable_labels=True) # Store some parameters in the dict widget frame.inner_trait = inner_trait frame.trait = trait frame.controller = controller frame.controller_widget = controller_widget frame.connected = False # Add the dict controller widget to the dict widget frame.setLayout(controller_widget.layout()) # Set some callback on the dict control tools # Resize callback resize_hook = partial( DictControlWidget.expand_or_collapse, weak_proxy(frame), weak_proxy(resize_button)) resize_button.clicked.connect(resize_hook) # Add dict item callback add_hook = partial( DictControlWidget.add_dict_item, parent, control_name, frame) add_button.clicked.connect(add_hook) # Create the label associated with the dict widget control_label = trait.label if control_label is None: control_label = control_name if label_class is None: label_class = QtGui.QLabel if control_label is not None: label = label_class(control_label, parent) else: label = None controller_widget.main_controller_def = (DictControlWidget, parent, control_name, frame) return (frame, (label, tool_widget))
def create_widget(parent, control_name, control_value, trait, label_class=None): """ Method to create the file widget. Parameters ---------- parent: QWidget (mandatory) the parent widget control_name: str (mandatory) the name of the control we want to create control_value: str (mandatory) the default control value trait: Tait (mandatory) the trait associated to the control label_class: Qt widget class (optional, default: None) the label widget will be an instance of this class. Its constructor will be called using 2 arguments: the label string and the parent widget. Returns ------- out: 2-uplet a two element tuple of the form (control widget: QWidget with two elements, a QLineEdit in the 'path' parameter and a browse button in the 'browse' parameter, associated label: QLabel) """ # Create the widget that will be used to select a file widget = QtGui.QWidget(parent) layout = QtGui.QHBoxLayout() layout.setSpacing(0) layout.setSizeConstraint(QtGui.QLayout.SetMinimumSize) layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) # Create a widget to print the file path path = TimeredQLineEdit(widget) layout.addWidget(path) widget.path = path # Create a browse button button = QtGui.QPushButton("...", widget) button.setObjectName('file_button') button.setStyleSheet('QPushButton#file_button ' '{padding: 2px 10px 2px 10px; margin: 0px;}') layout.addWidget(button) widget.browse = button # Add a widget parameter to tell us if the widget is already connected widget.connected = False # Add a parameter to tell us if the widget is optional widget.optional = trait.optional widget.output = trait.output # Set a callback on the browse button control_class = parent.get_control_class(trait) browse_hook = partial(control_class.onBrowseClicked, weak_proxy(widget)) widget.browse.clicked.connect(browse_hook) # Create the label associated with the string widget control_label = trait.label if control_label is None: control_label = control_name if label_class is None: label_class = QtGui.QLabel if control_label is not None: label = label_class(control_label, parent) else: label = None return (widget, label)
def connect(cls, controller_widget, control_name, control_instance): """ Connect a 'List' controller trait and an 'OffscreenListControlWidget' controller widget control. Parameters ---------- cls: StrControlWidget (mandatory) a StrControlWidget control controller_widget: ControllerWidget (mandatory) a controller widget that contains the controller we want to update control_name: str (mandatory) the name of the controller widget control we want to synchronize with the controller control_instance: QFrame (mandatory) the instance of the controller widget control we want to synchronize with the controller """ # Check if the control is connected if not control_instance.connected: # Update the list item when one of his associated controller trait # changed. # Hook: function that will be called to update the controller # associated with a list widget when a list widget inner controller # trait is modified. list_controller_hook = SomaPartial(cls.update_controller, weak_proxy(controller_widget), control_name, weak_proxy(control_instance)) # Go through all list widget inner controller user traits for trait_name in control_instance.controller.user_traits(): # And add the callback on each user trait control_instance.controller.on_trait_change( list_controller_hook, trait_name, dispatch='ui') logger.debug("Item '{0}' of a 'ListControlWidget', add " "a callback on inner controller trait " "'{0}'.".format(control_name, trait_name)) # Update the list controller widget. # Hook: function that will be called to update the specific widget # when a trait event is detected on the list controller. controller_hook = SomaPartial(cls.update_controller_widget, weak_proxy(controller_widget), control_name, weak_proxy(control_instance)) # When the 'control_name' controller trait value is modified, # update the corresponding control controller_widget.controller.on_trait_change(controller_hook, control_name, dispatch='ui') # Update the list connection status control_instance._controller_connections = (list_controller_hook, controller_hook) logger.debug("Add 'List' connection: {0}.".format( control_instance._controller_connections)) # Update the list control connection status control_instance.connected = True
def create_widget(parent, control_name, control_value, trait, label_class=None, user_data=None): """ Method to create the list widget. Parameters ---------- parent: QWidget (mandatory) the parent widget control_name: str (mandatory) the name of the control we want to create control_value: list of items (mandatory) the default control value trait: Tait (mandatory) the trait associated to the control label_class: Qt widget class (optional, default: None) the label widget will be an instance of this class. Its constructor will be called using 2 arguments: the label string and the parent widget. Returns ------- out: 2-uplet a two element tuple of the form (control widget: , associated labels: (a label QLabel, the tools QWidget)) """ # Get the inner trait: expect only one inner trait # note: trait.inner_traits might be a method (ListInt) or a tuple # (List), whereas trait.handler.inner_trait is always a method if len(trait.handler.inner_traits()) != 1: raise Exception( "Expect only one inner trait in List control. Trait '{0}' " "inner trait is '{1}'.".format(control_name, trait.handler.inner_traits())) inner_trait = trait.handler.inner_traits()[0] # Create the widget frame = QtGui.QFrame() frame.setFrameShape(QtGui.QFrame.StyledPanel) frame.user_data = user_data layout = QtGui.QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) frame.setLayout(layout) #item = QtGui.QLabel('<list of %s>' #% str(inner_trait.trait_type.__class__.__name__)) #item.setTextInteractionFlags(QtCore.Qt.TextSelectableByKeyboard | #QtCore.Qt.TextSelectableByMouse) #item.setFrameStyle(QtGui.QFrame.StyledPanel | QtGui.QFrame.Sunken) #layout.addWidget(item) # Create tools to interact with the list widget: expand or collapse - # add a list item - remove a list item tool_widget = QtGui.QWidget(parent) layout.addWidget(tool_widget) layout = QtGui.QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(2) tool_widget.setLayout(layout) # Store some parameters in the list widget frame.inner_trait = inner_trait frame.trait = trait frame.connected = False if control_value is traits.Undefined: control_value = [] elif not isinstance(control_value, (list, tuple)): # in nipype MultiPath, single values are not in a list control_value = [control_value] frame.trait_name = control_name # Create the label associated with the list widget control_label = trait.label if control_label is None: control_label = control_name if label_class is None: label_class = QtGui.QLabel if control_label is not None: label = label_class(control_label, parent) else: label = None frame.label_class = label_class # view the model items = OffscreenListControlWidget.partial_view_widget( weak_proxy(parent), weak_proxy(frame), control_value) layout.addWidget(items) #layout.addWidget(QtGui.QLabel('...')) frame.control_widget = items frame.controller = items.control_widget.controller frame.controller_widget = items.control_widget.controller_widget # Create the tool buttons edit_button = QtGui.QToolButton() layout.addWidget(edit_button) # Set the tool icons icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/add")), QtGui.QIcon.Normal, QtGui.QIcon.Off) edit_button.setIcon(icon) edit_button.setFixedSize(30, 22) #layout.addStretch(1) # Set some callback on the list control tools # Resize callback edit_hook = partial(OffscreenListControlWidget.edit_elements, weak_proxy(parent), weak_proxy(frame), weak_proxy(edit_button)) edit_button.clicked.connect(edit_hook) return (frame, label)
def create_widget(parent, control_name, control_value, trait, label_class=None, max_items=0): """ Method to create the list widget. Parameters ---------- parent: QWidget (mandatory) the parent widget control_name: str (mandatory) the name of the control we want to create control_value: list of items (mandatory) the default control value trait: Tait (mandatory) the trait associated to the control label_class: Qt widget class (optional, default: None) the label widget will be an instance of this class. Its constructor will be called using 2 arguments: the label string and the parent widget. max_items: int (optional) display at most this number of items. Defaults to 0: no limit. Returns ------- out: 2-uplet a two element tuple of the form (control widget: , associated labels: (a label QLabel, the tools QWidget)) """ # Get the inner trait: expect only one inner trait # note: trait.inner_traits might be a method (ListInt) or a tuple # (List), whereas trait.handler.inner_trait is always a method if len(trait.handler.inner_traits()) == 1: inner_trait = trait.handler.inner_traits()[0] elif len(trait.handler.inner_traits()) == 0: # maybe a generic list, or a compount trait if hasattr(trait.handler, 'handlers') \ and len(trait.handler.handlers) > 0 \ and hasattr(trait.handler.handlers[0], 'inner_traits') \ and len(trait.handler.handlers[0].inner_traits()) > 0: inner_trait = trait.handler.handlers[0].inner_traits()[0] else: # can't determine type, fallback to string inner_trait = traits.Str() else: raise Exception( "Expect only one inner trait in List control. Trait '{0}' " "inner trait is '{1}'.".format(control_name, trait.handler.inner_traits())) if control_value is traits.Undefined: control_value = [] # Create the list widget: a frame parent = get_ref(parent) frame = QtGui.QFrame(parent=parent) #frame.setFrameShape(QtGui.QFrame.StyledPanel) frame.setFrameShape(QtGui.QFrame.NoFrame) # Create tools to interact with the list widget: expand or collapse - # add a list item - remove a list item tool_widget = QtGui.QWidget(parent) layout = QtGui.QHBoxLayout() layout.addStretch(1) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(2) tool_widget.setLayout(layout) # Create the tool buttons resize_button = QtGui.QToolButton() add_button = QtGui.QToolButton() delete_button = QtGui.QToolButton() layout.addWidget(resize_button) layout.addWidget(add_button) layout.addWidget(delete_button) # Set the tool icons icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/add")), QtGui.QIcon.Normal, QtGui.QIcon.Off) add_button.setIcon(icon) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/delete")), QtGui.QIcon.Normal, QtGui.QIcon.Off) delete_button.setIcon(icon) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_down")), QtGui.QIcon.Normal, QtGui.QIcon.Off) resize_button.setIcon(icon) resize_button.setFixedSize(30, 22) add_button.setFixedSize(40, 22) delete_button.setFixedSize(40, 22) menu = QtGui.QMenu() menu.addAction( 'Enter list', partial(ListControlWidget.enter_list, weak_proxy(parent), control_name, weak_proxy(frame))) menu.addAction( 'Load list', partial(ListControlWidget.load_list, weak_proxy(parent), control_name, weak_proxy(frame))) if isinstance(inner_trait.trait_type, traits.File) \ or isinstance(inner_trait.trait_type, traits.Directory): menu.addAction( 'Select files', partial(ListControlWidget.select_files, weak_proxy(parent), control_name, weak_proxy(frame))) add_button.setMenu(menu) menu = QtGui.QMenu() menu.addAction( 'Clear all', partial(ListControlWidget.clear_all, weak_proxy(parent), control_name, weak_proxy(frame), trait.trait_type.minlen)) delete_button.setMenu(menu) # Create a new controller that contains length 'control_value' inner # trait elements controller = ListController() if inner_trait.groups: del inner_trait.groups n = max_items if n == 0: n = len(control_value) for cnt, inner_control_values in enumerate(control_value[:n]): controller.add_trait(str(cnt), inner_trait) #if inner_trait.groups: #del trait(str(cnt)).groups setattr(controller, str(cnt), inner_control_values) # Create the associated controller widget controller_widget = ControllerWidget(controller, parent=frame, live=True) controller_widget.setObjectName('inner_controller') controller_widget.setStyleSheet( 'ControllerWidget#inner_controller { padding: 0px; }') # Store some parameters in the list widget frame.inner_trait = inner_trait frame.trait = trait frame.controller = controller frame.controller_widget = controller_widget frame.connected = False frame.max_items = max_items # Add the list controller widget to the list widget frame.setLayout(controller_widget.layout()) frame.layout().setContentsMargins(0, 0, 0, 0) frame.setObjectName('inner_frame') frame.setStyleSheet('QFrame#inner_frame { padding: 0px; }') # Set some callback on the list control tools # Resize callback resize_hook = partial(ListControlWidget.expand_or_collapse, weak_proxy(frame), weak_proxy(resize_button)) resize_button.clicked.connect(resize_hook) # Add list item callback add_hook = partial(ListControlWidget.add_list_item, weak_proxy(parent), control_name, weak_proxy(frame)) add_button.clicked.connect(add_hook) # Delete list item callback delete_hook = partial(ListControlWidget.delete_list_item, weak_proxy(parent), control_name, weak_proxy(frame)) delete_button.clicked.connect(delete_hook) # Create the label associated with the list widget control_label = trait.label if control_label is None: control_label = control_name if label_class is None: label_class = QtGui.QLabel if control_label is not None: label = label_class(control_label, parent) else: label = None return (frame, (label, tool_widget))
def create_widget(parent, control_name, control_value, trait, label_class=None): """ Method to create the controller widget. Parameters ---------- parent: QWidget (mandatory) the parent widget control_name: str (mandatory) the name of the control we want to create control_value: instance of Controller (mandatory) the default control value trait: Tait (mandatory) the trait associated to the control label_class: Qt widget class (optional, default: None) the label widget will be an instance of this class. Its constructor will be called using 2 arguments: the label string and the parent widget. Returns ------- out: 2-uplet a two element tuple of the form (control widget: , associated labels: (a label QLabel, the tools QWidget)) """ # Create the list widget: a frame frame = QtGui.QFrame(parent=parent) frame.setFrameShape(QtGui.QFrame.StyledPanel) # Create tools to interact with the list widget: expand or collapse - # add a list item - remove a list item tool_widget = QtGui.QWidget(parent) layout = QtGui.QHBoxLayout() layout.addStretch(1) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(2) tool_widget.setLayout(layout) # Create the tool buttons resize_button = QtGui.QToolButton() layout.addWidget(resize_button) # Set the tool icons icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_down")), QtGui.QIcon.Normal, QtGui.QIcon.Off) resize_button.setIcon(icon) resize_button.setFixedSize(30, 22) editable_labels = False if trait.handler.inner_traits(): editable_labels = True frame.inner_trait = trait.handler.inner_traits()[0] add_button = QtGui.QToolButton() delete_button = QtGui.QToolButton() layout.addWidget(add_button) # Set the tool icons icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/add")), QtGui.QIcon.Normal, QtGui.QIcon.Off) add_button.setIcon(icon) add_button.setFixedSize(30, 22) delete_button.setFixedSize(30, 22) # Add list item callback add_hook = partial(ControllerControlWidget.add_item, weak_proxy(parent), control_name, weak_proxy(frame)) add_button.clicked.connect(add_hook) # Create the associated controller widget controller_widget = ControllerWidget(control_value, parent=frame, live=True, editable_labels=editable_labels) # Store some parameters in the list widget frame.trait = trait frame.controller = control_value frame.controller_widget = controller_widget frame.connected = False # Add the list controller widget to the list widget frame.setLayout(controller_widget.layout()) # Set some callback on the controller control tools # Resize callback resize_hook = partial(ControllerControlWidget.expand_or_collapse, weak_proxy(frame), weak_proxy(resize_button)) resize_button.clicked.connect(resize_hook) if getattr(trait, 'expanded') is False: ControllerControlWidget.set_expanded(frame, resize_button, False) # Create the label associated with the controller widget control_label = trait.label if control_label is None: control_label = control_name if label_class is None: label_class = QtGui.QLabel if control_label is not None: label = label_class(control_label, parent) else: label = None return (frame, (label, tool_widget))