def onHelpClicked(self): """ Event to display the documentation of the active pipeline. """ # Create a dialog box to display the html documentation win = QtGui.QDialog() win.setWindowTitle("Pipeline Help") # Build the pipeline documentation location # Possible since common tools generate the sphinx documentation if self.pipeline: # Generate the url to the active pipeline documentation path_to_active_pipeline_doc = os.path.join( self.path_to_pipeline_doc[self.pipeline.id], "generated", self.pipeline.id.split(".")[1], "pipeline", self.pipeline.id + ".html") # Create and fill a QWebView help = QtWebKit.QWebView() help.load(QtCore.QUrl(path_to_active_pipeline_doc)) help.show() # Create and set a layout with the web view layout = QtGui.QHBoxLayout() layout.addWidget(help) win.setLayout(layout) # Display the window win.exec_() # No Pipeline loaded, cant't show the documentation message # Display a message box else: QtGui.QMessageBox.information(self.ui, "Information", "First load a pipeline!")
def __init__(self, parent=None): """ Create a new QRangeSlider instance. :param parent: QWidget parent :return: New QRangeSlider instance. """ QtGui.QWidget.__init__(self, parent) self.setupUi(self) self.setMouseTracking(False) self._splitter.splitterMoved.connect(self._handleMoveSplitter) # head layout self._head_layout = QtGui.QHBoxLayout() self._head_layout.setSpacing(0) self._head_layout.setContentsMargins(0, 0, 0, 0) self._head.setLayout(self._head_layout) self.head = Head(self._head, main=self) self._head_layout.addWidget(self.head) # handle layout self._handle_layout = QtGui.QHBoxLayout() self._handle_layout.setSpacing(0) self._handle_layout.setContentsMargins(0, 0, 0, 0) self._handle.setLayout(self._handle_layout) self.handle = Handle(self._handle, main=self) self.handle.setTextColor((150, 255, 150)) self._handle_layout.addWidget(self.handle) # tail layout self._tail_layout = QtGui.QHBoxLayout() self._tail_layout.setSpacing(0) self._tail_layout.setContentsMargins(0, 0, 0, 0) self._tail.setLayout(self._tail_layout) self.tail = Tail(self._tail, main=self) self._tail_layout.addWidget(self.tail) # defaults self.setMin(0) self.setMax(99) self.setStart(0) self.setEnd(99) self.setDrawValues(True) self._movingHandle = False
def __init__(self, parent, controller_widget, control_name): super(ListValuesEditor, self).__init__(parent) self.controller_widget = controller_widget self.control_name = control_name self.format = 'JSON' self.separator = ',' self.modified = False layout = QtGui.QVBoxLayout() self.setLayout(layout) textedit = QtGui.QTextEdit() layout.addWidget(textedit) hlayout2 = QtGui.QHBoxLayout() layout.addLayout(hlayout2) hlayout2.addWidget(QtGui.QLabel('Format:')) format_c = QtGui.QComboBox() hlayout2.addWidget(format_c) hlayout2.addWidget(QtGui.QLabel('Separator:')) sep_c = QtGui.QComboBox() hlayout2.addWidget(sep_c) format_c.addItem('JSON') format_c.addItem('CSV') sep_c.addItem(',') sep_c.addItem(';') sep_c.addItem(' ') hlayout2.addStretch(1) ok = QtGui.QPushButton('OK') cancel = QtGui.QPushButton('Cancel') hlayout2.addWidget(ok) hlayout2.addWidget(cancel) ok.pressed.connect(self.accept) cancel.pressed.connect(self.reject) parent_controller = controller_widget.controller value = getattr(parent_controller, control_name) text = json.dumps(value) textedit.setText(text) self.textedit = textedit self.format_c = format_c self.separator_c = sep_c self.internal_change = False textedit.textChanged.connect(self.set_modified) format_c.currentIndexChanged.connect(self.format_changed) sep_c.currentIndexChanged.connect(self.separator_changed)
def _create_group_widget(self, group): group_widget = QtGui.QGroupBox() last_row = self._grid_layout.rowCount() self._grid_layout.addWidget(group_widget, last_row, 0, 1, 2) lay1 = QtGui.QVBoxLayout() lay1.setContentsMargins(0, 0, 0, 0) lay2 = QtGui.QHBoxLayout() lay1.addLayout(lay2) lay2.setContentsMargins(10, 0, 0, 0) lay2.addWidget(QtGui.QLabel('<html><em>%s</em></html>' % group)) lay2.addStretch(1) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_down")), QtGui.QIcon.Normal, QtGui.QIcon.Off) group_widget.fold_button = QtGui.QPushButton(icon, '') group_widget.fold_button.setFixedSize(30, 20) lay2.addWidget(group_widget.fold_button) widget = QtGui.QWidget() group_widget.setLayout(lay1) lay1.addWidget(widget) group_widget.hideable_widget = widget layout = QtGui.QGridLayout() widget.setLayout(layout) layout.setAlignment(QtCore.Qt.AlignTop) layout.setSpacing(3) layout.setContentsMargins(5, 5, 5, 5) group_widget.setAlignment(QtCore.Qt.AlignLeft) visible_groups = getattr(self.controller, 'visible_groups', set()) if group in visible_groups: show = True else: show = False group_widget.hideable_widget.setVisible(show) if not show: icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_right")), QtGui.QIcon.Normal, QtGui.QIcon.Off) group_widget.fold_button.setIcon(icon) #group_widget.fold_button.clicked.connect(SomaPartial( #self._toggle_group_visibility, group)) # FIXME: if we use this, self gets deleted somewhere. This is not # normal. group_widget.fold_button.clicked.connect( partial(self.__class__._toggle_group_visibility, weak_proxy(self), group)) return group_widget
def __init__(self, text=None, parent=None): super(DeletableLineEdit, self).__init__(parent) layout = QtGui.QHBoxLayout() self.setLayout(layout) delete_button = QtGui.QToolButton() layout.addWidget(delete_button) # Set the tool icons icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/delete")), QtGui.QIcon.Normal, QtGui.QIcon.Off) delete_button.setIcon(icon) self.line_edit = TimeredQLineEdit(text) layout.addWidget(self.line_edit) self.line_edit.userModification.connect(self.userModification) delete_button.pressed.connect(self.buttonPressed)
def _completion_progress_changed(self, obj, name, old, new): completion_engine = getattr(self.attributed_process, 'completion_engine', None) if completion_engine is not None: if not hasattr(self, 'progressdialog'): self.progressdialog = QtGui.QWidget() self.layout().insertWidget(1, self.progressdialog) layout = QtGui.QHBoxLayout() self.progressdialog.setLayout(layout) layout.addWidget(QtGui.QLabel('Completion progress:')) self.progressbar = QtGui.QProgressBar() layout.addWidget(self.progressbar) self.progressbar.setRange(0, 100) value = int(round(100 * completion_engine.completion_progress / completion_engine.completion_progress_total)) self.progressbar.setValue(value) if value != 100: self.progressdialog.show() QtGui.qApp.processEvents() else: self.progressdialog.hide()
def __init__(self, app=None): QtGui.QDialog.__init__(self) self.ui = uic.loadUi("locateleds.ui", self) self.pb = plasticbrain.PlasticBrain() self.ui.startLocaButton.clicked.connect(self.start) self.ui.loadMeshButton.clicked.connect(self.loadMesh) self.ui.deviceCombo.currentIndexChanged.connect( self.updatedDeviceCombo) self.ui.saveButton.clicked.connect(self.save) self.ui.nextLedButton.clicked.connect(self.nextLed) self.ui.previousLedButton.clicked.connect(self.previousLed) self.ui.ReceiveLSLButton.clicked.connect(self.ReceiveAndDisplayEEG) self.ui.StopReceiveData.clicked.connect(self.StopReceiveData) self.a = anatomist.Anatomist('-b') #Batch mode (hide Anatomist window) self.a.onCursorNotifier.add(self.clickHandler) pix = QtGui.QPixmap('control.xpm') self.app = app anatomistControl.cpp.IconDictionary.instance().addIcon( 'MyControl', pix) ad = anatomistControl.cpp.ActionDictionary.instance() ad.addAction('MyAction', lambda: MyAction()) cd = anatomistControl.cpp.ControlDictionary.instance() cd.addControl('MyControl', lambda: MyControl(), 25) cm = anatomistControl.cpp.ControlManager.instance() cm.addControl('QAGLWidget3D', '', 'MyControl') self.axWindow = self.a.createWindow('Axial') layoutAx = QtGui.QHBoxLayout(self.frame) self.axWindow.setParent(self.frame) layoutAx.addWidget(self.axWindow.getInternalRep()) self.currentElec = 0 self.coords = [ [0, 0, 0], ] self.mesh = None self.aimsMesh = None self.texture = None self.currentObj = None self.TextObj = None
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 edit_elements(controller_widget, control_instance, edit_button): """ Callback to view/edit a 'ListControlWidget'. Parameters ---------- control_instance: QFrame (mandatory) the list widget item edit_button: QToolButton the signal sender """ controller_widget = get_ref(controller_widget) widget = QtGui.QDialog(controller_widget) widget.setModal(True) layout = QtGui.QVBoxLayout() widget.setLayout(layout) #hlayout = QtGui.QHBoxLayout() #layout.addLayout(hlayout) temp_controller = Controller() trait = control_instance.trait temp_controller.add_trait(control_instance.trait_name, trait) if temp_controller.trait(control_instance.trait_name).groups \ is not None: temp_controller.trait(control_instance.trait_name).groups = None value = getattr(controller_widget.controller, control_instance.trait_name) try: setattr(temp_controller, control_instance.trait_name, value) except Exception: # invalid value - don't prevent using the GUI pass control_types = dict(controller_widget._defined_controls) control_types['List'] = ListControlWidget control_types['List_File'] = ListControlWidget temp_controller_widget = ScrollControllerWidget( temp_controller, live=True, override_control_types=control_types, user_data=control_instance.user_data) layout.addWidget(temp_controller_widget) hlayout2 = QtGui.QHBoxLayout() layout.addLayout(hlayout2) hlayout2.addStretch(1) ok = QtGui.QPushButton('OK') cancel = QtGui.QPushButton('Cancel') hlayout2.addWidget(ok) hlayout2.addWidget(cancel) ok.pressed.connect(widget.accept) cancel.pressed.connect(widget.reject) if widget.exec_(): ctrl = temp_controller_widget.controller_widget._controls.get( control_instance.trait_name)[None] ListControlWidget.validate_all_values( temp_controller_widget.controller_widget, ctrl[2]) new_trait_value = getattr(temp_controller, control_instance.trait_name) setattr(controller_widget.controller, control_instance.trait_name, new_trait_value) del temp_controller_widget
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 _fill_trees(self): """ Method to insert processing parameters in the class trees. """ # Generate structures that contain all viewers and all processings # status - metainforamtion viewers_struct = {} processings_struct = [] # Go through all the controller (pipeline) nodes. for node_name, node in six.iteritems(self.controller.nodes): # If the current node is a processing node if node_name != "" and node.node_type != "view_node": # First browse the current node to get processings and viewers process_nodes = [] view_nodes = [] self.browse_node( node, process_nodes, view_nodes, self.controller) # Set process logs #for process_node in process_nodes: # widget = LogWidget(process_node) # widget.setParent(root.treeWidget()) # child.treeWidget().setItemWidget(child, 3, widget) # Fill the processing structure for processing_node in process_nodes: processings_struct.append({ "name": processing_node.name, "log": processing_node.process.log_file or "No log"}) # Fill the viewer structure for viewer_node, pipeline in view_nodes: # Create a viewer widget (a simple press button) widget = ViewerWidget(viewer_node.name, pipeline, None) #self._study_config) # Store the widget in the corresponding structure title = self._title_for(pipeline.name) if title not in viewers_struct: viewers_struct[title] = [] viewers_struct[title].append(widget) # If the current node is a viewer node elif node.node_type == "view_node": # Create a viewer widget (a simple press button) widget = ViewerWidget(node_name, self.controller, None) #self._study_config) # Store the widget in the corresponding structure title = self._title_for(self.controller.name) if title not in viewers_struct: viewers_struct[title] = [] viewers_struct[title].append(widget) # Fill the viewer tree widget viewer_parent = self.viewer_tree.invisibleRootItem() for pipeline_title, viewer_widgets in six.iteritems(viewers_struct): # Create a new tree item viewer_child = QtGui.QTreeWidgetItem(viewer_parent) viewer_child.setText(0, pipeline_title) # Set the viewer widgets in a layout widget_layout = QtGui.QHBoxLayout() widget_layout.setSpacing(0) widget_layout.setSizeConstraint(QtGui.QLayout.SetMinimumSize) widget_layout.setContentsMargins(0, 0, 0, 0) widget_layout.addStretch(1) for widget in viewer_widgets: widget = QtGui.QToolButton() widget_layout.addWidget(widget) # Set the final widget tree item widget = QtGui.QWidget(viewer_child.treeWidget()) widget.setLayout(widget_layout) viewer_child.treeWidget().setItemWidget(viewer_child, 1, widget) # Fill the pboard tree widget board_parent = self.board_tree.invisibleRootItem() for process_info in processings_struct: # Create a new tree item board_child = QtGui.QTreeWidgetItem(board_parent) board_child.setText(0, process_info["name"]) board_child.setText(4, process_info["log"])
def __init__(self, attributed_process, enable_attr_from_filename=False, enable_load_buttons=False, override_control_types=None, separate_outputs=True, user_data=None, userlevel=0, scroll=True): """ Parameters ---------- attributed_process: Process instance process with attributes to be displayed enable_attr_from_filename: bool (optional) if enabled, it will be possible to specify an input filename to build attributes from override_control_types: dict (optional) if given, this is a "factory" dict assigning new controller editor types to some traits types in the parameters controller. separate_outputs: bool if True, inputs and outputs (traits with output=True set) will be separated into two boxes. user_data: any type (optional) optional user data that can be accessed by individual control editors userlevel: int the current user level: some traits may be marked with a non-zero userlevel, and will only be visible if the ControllerWidget userlevel is more than (or equal) the trait level. scroll: bool if True, the widget includes scrollbars in the parameters and attributes sections when needed, otherwise it will be a fixed size widget. """ super(AttributedProcessWidget, self).__init__() self.setLayout(QtGui.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.attributed_process = attributed_process self._show_completion = False self.user_data = user_data self.separate_outputs = separate_outputs self._userlevel = userlevel process = attributed_process completion_engine = getattr(process, 'completion_engine', None) if completion_engine is not None: splitter = QtGui.QSplitter(QtCore.Qt.Vertical) self.layout().addWidget(splitter) spl_up = QtGui.QWidget() spl_up.setLayout(QtGui.QVBoxLayout()) splitter.addWidget(spl_up) spl_down = QtGui.QWidget() spl_down.setLayout(QtGui.QVBoxLayout()) splitter.addWidget(spl_down) else: spl_up = self spl_down = self filename_widget = None if enable_attr_from_filename and completion_engine is not None: c = Controller() c.add_trait('attributes_from_input_filename', File(optional=True)) filename_widget = ControllerWidget(c, live=True, user_data=user_data) spl_up.layout().addWidget(filename_widget) self.input_filename_controller = c c.on_trait_change(self.on_input_filename_changed, 'attributes_from_input_filename', dispatch='ui') filename_widget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) # groupbox area to show attributes attrib_widget = QtGui.QGroupBox('Attributes:') attrib_widget.setFlat(True) attrib_widget.setAlignment(QtCore.Qt.AlignLeft) attrib_widget.setLayout(QtGui.QVBoxLayout()) self.attrib_widget = attrib_widget spl_up.layout().addWidget(attrib_widget) attrib_widget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) hlay = QtGui.QHBoxLayout() spl_up.layout().addLayout(hlay) # CheckBox to completion rules or not self.checkbox_fom = QtGui.QCheckBox('Follow completion rules') self.checkbox_fom.setChecked(True) self.checkbox_fom.stateChanged.connect(self.on_use_fom_change) hlay.addWidget(self.checkbox_fom) # Button Show/Hide completion self.btn_show_completion = QtGui.QCheckBox('Show completion') self.btn_show_completion.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) hlay.addWidget(self.btn_show_completion) self.btn_show_completion.stateChanged.connect(self.on_show_completion) params = QtGui.QWidget() playout = QtGui.QVBoxLayout() params.setLayout(playout) if scroll: scroll_a = QtGui.QScrollArea() scroll_a.setWidgetResizable(True) scroll_a.setWidget(params) spl_up.layout().addWidget(scroll_a) scroll_a.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) params.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) CWidgetClass = ScrollControllerWidget else: spl_up.layout().addWidget(params) CWidgetClass = ControllerWidget # groupbox area to show completion if separate_outputs: param_widget = QtGui.QGroupBox('Inputs:') else: param_widget = QtGui.QGroupBox('Parameters:') param_widget.setFlat(True) param_widget.setAlignment(QtCore.Qt.AlignLeft) playout.addWidget(param_widget) param_widget.setLayout(QtGui.QVBoxLayout()) param_widget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) if separate_outputs: out_widget = QtGui.QGroupBox('Outputs:') out_widget.setFlat(True) out_widget.setAlignment(QtCore.Qt.AlignLeft) playout.addWidget(out_widget) out_widget.setLayout(QtGui.QVBoxLayout()) out_widget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) # use concise shape for lists GUI from soma.qt_gui.controls import OffscreenListControlWidget control_types_a = {'List': OffscreenListControlWidget} control_types_p = {'List': OffscreenListControlWidget} if override_control_types: control_types_p.update(override_control_types) #ControllerWidget._defined_controls['List'] = OffscreenListControlWidget # Create controller widget for process and object_attribute sel = None if separate_outputs: sel = 'inputs' self.controller_widget = ControllerWidget(process, live=True, parent=param_widget, override_control_types=control_types_p, user_data=user_data, userlevel=userlevel, select_controls=sel) if separate_outputs: self.outputs_cwidget = ControllerWidget(process, live=True, parent=out_widget, override_control_types=control_types_p, user_data=user_data, userlevel=userlevel, select_controls='outputs') show_ce = (completion_engine is not None and len( completion_engine.get_attribute_values().user_traits()) != 0) if completion_engine is not None: self.controller_widget2 = CWidgetClass( completion_engine.get_attribute_values(), live=True, parent=attrib_widget, override_control_types=control_types_a, user_data=user_data, userlevel=userlevel) completion_engine.get_attribute_values().on_trait_change( completion_engine.attributes_changed, 'anytrait') else: self.controller_widget2 = CWidgetClass( Controller(), override_control_types=control_types_a, user_data=user_data, userlevel=userlevel) # Set controller of attributes and controller of process for each # corresponding area param_widget.layout().addWidget(self.controller_widget) if separate_outputs: out_widget.layout().addWidget(self.outputs_cwidget) attrib_widget.layout().addWidget(self.controller_widget2) if enable_load_buttons and completion_engine is not None: io_lay = QtGui.QHBoxLayout() self.layout().addLayout(io_lay) self.btn_load_json = QtGui.QPushButton('Load attributes') io_lay.addWidget(self.btn_load_json) self.btn_load_json.clicked.connect(self.on_btn_load_json) self.btn_save_json = QtGui.QPushButton('Save attributes') io_lay.addWidget(self.btn_save_json) self.btn_save_json.clicked.connect(self.on_btn_save_json) if not show_ce: if filename_widget: filename_widget.hide() attrib_widget.hide() self.checkbox_fom.hide() self.btn_show_completion.hide() if hasattr(self, 'btn_load_json'): self.btn_load_json.hide() self.btn_save_json.hide() self.show_completion(True) # hide file parts else: self.show_completion(False) # hide file parts if completion_engine is not None: completion_engine.on_trait_change( self._completion_progress_changed, 'completion_progress', dispatch='ui')
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))
def __init__(self, attributed_process, enable_attr_from_filename=False, enable_load_buttons=False): """ Parameters ---------- attributed_process: Process instance process with attributes to be displayed enable_attr_from_filename: bool (optional) if enabled, it will be possible to specify an input filename to build attributes from """ super(AttributedProcessWidget, self).__init__() self.setLayout(QtGui.QVBoxLayout()) self.attributed_process = attributed_process self._show_completion = False process = attributed_process completion_engine = getattr(process, 'completion_engine', None) if completion_engine is not None: splitter = QtGui.QSplitter(QtCore.Qt.Vertical) self.layout().addWidget(splitter) spl_up = QtGui.QWidget() spl_up.setLayout(QtGui.QVBoxLayout()) splitter.addWidget(spl_up) spl_down = QtGui.QWidget() spl_down.setLayout(QtGui.QVBoxLayout()) splitter.addWidget(spl_down) else: spl_up = self spl_down = self if enable_attr_from_filename and completion_engine is not None: c = Controller() c.add_trait('attributes_from_input_filename', File(optional=True)) cw = ControllerWidget(c, live=True) spl_up.layout().addWidget(cw) self.input_filename_controller = c c.on_trait_change(self.on_input_filename_changed, 'attributes_from_input_filename', dispatch='ui') cw.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) # groupbox area to show attributs attrib_widget = QtGui.QGroupBox('Attributes:') attrib_widget.setAlignment(QtCore.Qt.AlignLeft) attrib_widget.setLayout(QtGui.QVBoxLayout()) self.attrib_widget = attrib_widget spl_up.layout().addWidget(attrib_widget) attrib_widget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) hlay = QtGui.QHBoxLayout() spl_up.layout().addLayout(hlay) # CheckBox to completion rules or not self.checkbox_fom = QtGui.QCheckBox('Follow completion rules') self.checkbox_fom.setChecked(True) self.checkbox_fom.stateChanged.connect(self.on_use_fom_change) hlay.addWidget(self.checkbox_fom) # Button Show/Hide completion self.btn_show_completion = QtGui.QCheckBox('Show completion') self.btn_show_completion.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) hlay.addWidget(self.btn_show_completion) self.btn_show_completion.stateChanged.connect(self.on_show_completion) # groupbox area to show completion param_widget = QtGui.QGroupBox('Parameters:') param_widget.setAlignment(QtCore.Qt.AlignLeft) spl_down.layout().addWidget(param_widget) param_widget.setLayout(QtGui.QVBoxLayout()) param_widget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) # Create controller widget for process and object_attribute self.controller_widget = ScrollControllerWidget(process, live=True, parent=param_widget) if completion_engine is not None: self.controller_widget2 = ScrollControllerWidget( completion_engine.get_attribute_values(), live=True, parent=attrib_widget) completion_engine.get_attribute_values().on_trait_change( completion_engine.attributes_changed, 'anytrait') else: self.controller_widget2 = ScrollControllerWidget(Controller()) # Set controller of attributs and controller of process for each # corresponding area param_widget.layout().addWidget(self.controller_widget) attrib_widget.layout().addWidget(self.controller_widget2) if enable_load_buttons and completion_engine is not None: io_lay = QtGui.QHBoxLayout() self.layout().addLayout(io_lay) self.btn_load_json = QtGui.QPushButton('Load attributes') io_lay.addWidget(self.btn_load_json) self.btn_load_json.clicked.connect(self.on_btn_load_json) self.btn_save_json = QtGui.QPushButton('Save attributes') io_lay.addWidget(self.btn_save_json) self.btn_save_json.clicked.connect(self.on_btn_save_json) if completion_engine is None: attrib_widget.hide() self.checkbox_fom.hide() self.btn_show_completion.hide() self.show_completion(True) # hide file parts else: self.show_completion(False) # hide file parts if completion_engine is not None: completion_engine.on_trait_change( self._completion_progress_changed, 'completion_progress', dispatch='ui')