Beispiel #1
0
    def addHandlerRules(self, module, handlersList=[], *args, **kwargs):
        '''
        This method is used to add handler rules (renaming rule, deleting rule, ...) .

        @module module: module object to apply rules to.
        @handlersList list: a list of handlers to the module.
        '''
        for handler in handlersList:
            self.addPartialRules(module, [partial(handler, *args, **kwargs)])
Beispiel #2
0
 def connect_keys(self):
     if not self.editable_labels or self._keys_connections:
         return
     keys_connect = {}
     # Go through all the controller widget controls
     for control_name, control_groups in six.iteritems(self._controls):
         for group_name, control in six.iteritems(control_groups):
             hook1 = partial(self.__class__._key_modified,
                             weakref.proxy(self), control_name)
             hook2 = partial(self.__class__._delete_key,
                             weakref.proxy(self), control_name)
             #control = self._controls[control_name]
             label_control = control[3]
             if isinstance(label_control, tuple):
                 label_control = label_control[0]
             label_control.userModification.connect(hook1)
             label_control.buttonPressed.connect(hook2)
             keys_connect[control_name] = (label_control, hook1, hook2)
     self._keys_connections = keys_connect
Beispiel #3
0
def loadUi(ui_file, *args, **kwargs):
    '''Load a ``.ui`` file and returns the widget instance.

    This function is a replacement of PyQt4.uic.loadUi. The only difference is
    that relative icon or pixmap file names that are stored in the ``*.ui``
    file are considered to be relative to the directory containing the ui file.
    With PyQt4.uic.loadUi, relative file names are considered relative to the
    current working directory therefore if this directory is not the one
    containing the ui file, icons cannot be loaded.
    '''
    from . import QtGui
    if get_qt_backend() in ('PyQt4', 'PyQt5'):
        # the problem is corrected in version > 4.7.2,
        from . import QtCore
        if QtCore.PYQT_VERSION > 0x040702:
            from . import uic
            return uic.loadUi(ui_file, *args, **kwargs)
        else:
            # needed import and def
            from .uic.Loader import loader
            if not hasattr(globals(), 'partial'):
                from soma.functiontools import partial

            def _iconset(self, prop):
                return QtGui.QIcon(
                    os.path.join(self._basedirectory,
                                 prop.text).replace("\\", "\\\\"))

            def _pixmap(self, prop):
                return QtGui.QPixmap(
                    os.path.join(self._basedirectory,
                                 prop.text).replace("\\", "\\\\"))

            uiLoader = loader.DynamicUILoader()
            uiLoader.wprops._basedirectory = os.path.dirname(
                os.path.abspath(ui_file))
            uiLoader.wprops._iconset = partial(_iconset, uiLoader.wprops)
            uiLoader.wprops._pixmap = partial(_pixmap, uiLoader.wprops)
            return uiLoader.loadUi(ui_file, *args, **kwargs)
    else:
        from PySide.QtUiTools import QUiLoader
        return QUiLoader().load(ui_file)  # , *args, **kwargs )
Beispiel #4
0
    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
Beispiel #5
0
    def connect(self):
        """ Connect the controller trait and the controller widget controls

        At the end al control will be connected with the associated trait, and
        when a 'user_traits_changed' signal is emited, the controls are updated
        (ie, deleted if necessary).
        """
        # If the controller and controller widget are not yet connected
        if not self.connected:

            # Go through all the controller widget controls
            for control_name, control_groups in six.iteritems(self._controls):
                for group_name, control in six.iteritems(control_groups):

                    # Unpack the control item
                    trait, control_class, control_instance, control_label \
                        = control

                    # Call the current control specific connection method
                    logger.debug("Connecting control '{0}: {1}'...".format(
                        control_name, control_instance))
                    control_class.connect(self, control_name, control_instance)

            # Add an event connected with the 'user_traits_changed' controller
            # signal: update the controls
            self.controller.on_trait_change(self.update_controls,
                                            "user_traits_changed",
                                            dispatch='ui')

            # if 'visible_groups' is a trait, connect it to groups
            if self.controller.trait('visible_groups'):
                self.controller.on_trait_change(self.groups_vibility_changed,
                                                'visible_groups',
                                                dispatch='ui')

            # Update the controller widget values
            self.update_controller_widget()

            # notifications should be removed when the GUI is destroyed
            # (on C++ side)
            self.destroyed.connect(
                partial(self.static_disconnect, self.controller,
                        self.update_controls, self.groups_vibility_changed,
                        self._controls))
            # Update the connection status
            self.connected = True
Beispiel #6
0
 def __getattr__(self, name):
     value = ThreadSafeProxy.pyroThreadCall(getattr, self._proxy, name)
     if isinstance(value,
                   Pyro.core._RemoteMethod) or inspect.ismethod(value):
         return partial(ThreadSafeProxy.pyroThreadCall, value)
     return value
Beispiel #7
0
    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))
Beispiel #8
0
    def create_control(self, trait_name, trait):
        """ Create a control associated to a trait.

        Parameters
        ----------
        trait_name: str (mandatory)
            the name of the trait from which we want to create a control. The
            control widget will share the same name
        trait: Trait (mandatory)
            a trait item
        """
        # Search if the current trait has already been processed
        control_groups = self._controls.get(trait_name)
        control_instances = []
        control_labels = []

        # If no control has been found in the class intern parameters
        if control_groups is None:

            # Call the search function that will map the trait type to the
            # corresponding control type
            control_class = self.get_control_class(trait)

            # If no control has been found, skip this trait and print
            # an error message. Note that the parameter will not be
            # accessible in the user interface.
            if control_class is None:
                logger.error("No control defined for trait '{0}': {1}. This "
                             "parameter will not be accessible in the "
                             "user interface.".format(trait_name,
                                                      trait_ids(trait)))
                return

            # handle groups
            layouts = []
            groups = trait.groups
            if groups:
                for group in groups:
                    group_widget = self._groups.get(group)
                    if group_widget is None:
                        group_widget = self._create_group_widget(group)
                        self._groups[group] = group_widget
                    layouts.append(group_widget.hideable_widget.layout())
            else:
                layouts.append(self._grid_layout)

            group = None
            for i, layout in enumerate(layouts):
                if groups:
                    group = groups[i]
                control_instance, control_label \
                      = self._create_control_in_layout(trait_name, trait,
                                                       layout, group)
                control_instances.append(control_instance)
                if control_label:
                    if not isinstance(control_label, tuple):
                        control_label = [control_label]
                    control_labels += list(control_label)
                    if isinstance(control_label[0], QtGui.QLabel):
                        control_label[0].setTextInteractionFlags(
                            QtCore.Qt.TextSelectableByKeyboard
                            | QtCore.Qt.TextSelectableByMouse)
                    control_label[0].setContextMenuPolicy(
                        Qt.Qt.CustomContextMenu)
                    control_label[0].customContextMenuRequested.connect(
                        partial(self._label_context_menu,
                                weakref.ref(control_label[0]), trait_name))

        # Otherwise, the control associated with the current trait name is
        # already inserted in the grid layout, just unpack the values
        # contained in the private '_controls' class parameter
        else:
            for group, control in six.iteritems(control_groups):
                _, _, control_instance, control_label = control
                control_instances.append(control_instance)
                if control_label:
                    if isinstance(control_label, tuple):
                        control_labels += list(control_label)
                    else:
                        control_labels.append(control_label)

        # Each trait has a hidden property. Take care of this information
        hide = (getattr(trait, 'hidden', False)
                or getattr(trait, 'unused', False)
                or (getattr(trait, 'userlevel', 0) is not None
                    and trait.userlevel > self.userlevel))

        # Show/Hide the control and associated labels
        for control_instance in control_instances:
            control_instance.setVisible(not hide)
        for label in control_labels:
            if not sip.isdeleted(label):  # sometimes happens...
                label.setVisible(not hide)