def create(self, parent): """ Create and set the toolkit-specific control that represents the pane. """ # Create and configure the tab widget. self.control = control = EditorAreaWidget(self, parent) self._filter = EditorAreaDropFilter(self) control.installEventFilter(self._filter) control.tabBar().setVisible(not self.hide_tab_bar) # Connect to the widget's signals. control.currentChanged.connect(self._update_active_editor) control.tabCloseRequested.connect(self._close_requested) # Add shortcuts for scrolling through tabs. if sys.platform == "darwin": next_seq = "Ctrl+}" prev_seq = "Ctrl+{" else: next_seq = "Ctrl+PgDown" prev_seq = "Ctrl+PgUp" shortcut = QtGui.QShortcut(QtGui.QKeySequence(next_seq), self.control) shortcut.activated.connect(self._next_tab) shortcut = QtGui.QShortcut(QtGui.QKeySequence(prev_seq), self.control) shortcut.activated.connect(self._previous_tab) # Add shortcuts for switching to a specific tab. mod = "Ctrl+" if sys.platform == "darwin" else "Alt+" mapper = QtCore.QSignalMapper(self.control) mapper.mapped.connect(self.control.setCurrentIndex) for i in range(1, 10): sequence = QtGui.QKeySequence(mod + str(i)) shortcut = QtGui.QShortcut(sequence, self.control) shortcut.activated.connect(mapper.map) mapper.setMapping(shortcut, i - 1)
def update_editor(self): """ Updates the editor when the object trait changes externally to the editor. """ self.mapper = QtCore.QSignalMapper(self.control) # Disconnect the editor from any control about to be destroyed: self._dispose_items() list_pane = self._list_pane layout = list_pane.layout() # Create all of the list item trait editors: trait_handler = self._trait_handler resizable = ((trait_handler.minlen != trait_handler.maxlen) and self.mutable) item_trait = trait_handler.item_trait is_fake = (resizable and (len(self.value) == 0)) if is_fake: self.empty_list() else: # Asking the mapper to send the sender to the callback method self.mapper.mapped[QtCore.QObject].connect(self.popup_menu) editor = self._editor for index, value in enumerate(self.value): row, column = divmod(index, self.factory.columns) # Account for the fact that we have <columns> number of # pairs column = column * 2 if resizable: # Connecting the new button to the mapper control = IconButton('list_editor.png', self.mapper.map) # Setting the mapping and asking it to send the index of the # sender to the callback method self.mapper.setMapping(control, control) layout.addWidget(control, row, column) proxy = ListItemProxy(self.object, self.name, index, item_trait, value) if resizable: control.proxy = proxy peditor = editor(self.ui, proxy, 'value', self.description, list_pane).set(object_name='') peditor.prepare(list_pane) pcontrol = peditor.control pcontrol.proxy = proxy if isinstance(pcontrol, QtGui.QWidget): layout.addWidget(pcontrol, row, column + 1) else: layout.addLayout(pcontrol, row, column + 1) # QScrollArea can have problems if the widget being scrolled is set too # early (ie. before it contains something). if self.control.widget() is None: self.control.setWidget(list_pane)
def create(self, parent): """ Create and set the toolkit-specific control that represents the pane. """ self.control = control = EditorAreaWidget(self, parent) self._filter = EditorAreaDropFilter(self) self.control.installEventFilter(self._filter) # Add shortcuts for scrolling through tabs. if sys.platform == 'darwin': next_seq = 'Ctrl+}' prev_seq = 'Ctrl+{' else: next_seq = 'Ctrl+PgDown' prev_seq = 'Ctrl+PgUp' shortcut = QtGui.QShortcut(QtGui.QKeySequence(next_seq), self.control) shortcut.activated.connect(self._next_tab) shortcut = QtGui.QShortcut(QtGui.QKeySequence(prev_seq), self.control) shortcut.activated.connect(self._previous_tab) # Add shortcuts for switching to a specific tab. mod = 'Ctrl+' if sys.platform == 'darwin' else 'Alt+' mapper = QtCore.QSignalMapper(self.control) mapper.mapped.connect(self._activate_tab) for i in xrange(1, 10): sequence = QtGui.QKeySequence(mod + str(i)) shortcut = QtGui.QShortcut(sequence, self.control) shortcut.activated.connect(mapper.map) mapper.setMapping(shortcut, i - 1)
def qt4_editor_factory(parent, editor, *args, **kwargs): from pyface.qt import QtCore, QtGui trait_handler = editor.factory.trait_handler if trait_handler is None: trait_handler = editor.object.base_trait(editor.name).handler editor._trait_handler = trait_handler editor.control = panel = QtGui.QScrollArea() editor.control.setFrameShape(QtGui.QFrame.NoFrame) editor.control.setWidgetResizable(True) editor.mapper = QtCore.QSignalMapper(panel) editor._list_pane = QtGui.QWidget() editor._list_pane.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) layout = QtGui.QGridLayout(editor._list_pane) layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) layout.setContentsMargins(0, 0, 0, 0) _editor = editor.factory.editor if _editor is None: _editor = trait_handler.item_trait.get_editor() editor._editor = getattr(_editor, editor.kind) extended_name = editor.extended_name.replace('.', ':') editor.context_object.on_trait_change(editor.update_editor_item, extended_name + '_items?', dispatch='ui') editor.set_tooltip() return panel
def set_key_bindings(self): """ Set keyboard shortcuts for tabbed navigation """ # Add shortcuts for scrolling through tabs. if sys.platform == "darwin": next_seq = "Ctrl+}" prev_seq = "Ctrl+{" else: next_seq = "Ctrl+PgDown" prev_seq = "Ctrl+PgUp" shortcut = QtGui.QShortcut(QtGui.QKeySequence(next_seq), self.control) shortcut.activated.connect(self._next_tab) self._connections_to_remove.append( (shortcut.activated, self._next_tab)) shortcut = QtGui.QShortcut(QtGui.QKeySequence(prev_seq), self.control) shortcut.activated.connect(self._previous_tab) self._connections_to_remove.append( (shortcut.activated, self._previous_tab)) # Add shortcuts for switching to a specific tab. mod = "Ctrl+" if sys.platform == "darwin" else "Alt+" mapper = QtCore.QSignalMapper(self.control) mapper.mapped.connect(self._activate_tab) self._connections_to_remove.append((mapper.mapped, self._activate_tab)) for i in range(1, 10): sequence = QtGui.QKeySequence(mod + str(i)) shortcut = QtGui.QShortcut(sequence, self.control) shortcut.activated.connect(mapper.map) self._connections_to_remove.append( (shortcut.activated, mapper.map)) mapper.setMapping(shortcut, i - 1)
def set_key_bindings(self): """ Set keyboard shortcuts for tabbed navigation """ # Add shortcuts for scrolling through tabs. if sys.platform == 'darwin': next_seq = 'Ctrl+}' prev_seq = 'Ctrl+{' elif sys.platform.startswith('linux'): next_seq = 'Ctrl+PgDown' prev_seq = 'Ctrl+PgUp' else: next_seq = 'Alt+n' prev_seq = 'Alt+p' shortcut = QtGui.QShortcut(QtGui.QKeySequence(next_seq), self.control) shortcut.activated.connect(self._next_tab) shortcut = QtGui.QShortcut(QtGui.QKeySequence(prev_seq), self.control) shortcut.activated.connect(self._previous_tab) # Add shortcuts for switching to a specific tab. mod = 'Ctrl+' if sys.platform == 'darwin' else 'Alt+' mapper = QtCore.QSignalMapper(self.control) mapper.mapped.connect(self._activate_tab) for i in xrange(1, 10): sequence = QtGui.QKeySequence(mod + str(i)) shortcut = QtGui.QShortcut(sequence, self.control) shortcut.activated.connect(mapper.map) mapper.setMapping(shortcut, i - 1)
def create_control(self, parent): """ Creates the initial editor control. """ self.control = QtGui.QWidget() layout = QtGui.QGridLayout(self.control) layout.setContentsMargins(0, 0, 0, 0) self._mapper = QtCore.QSignalMapper() self._mapper.mapped[str].connect(self.update_object)
def create_control ( self, parent ): """ Creates the initial editor control. """ self.control = QtGui.QWidget() layout = QtGui.QGridLayout(self.control) layout.setContentsMargins(0, 0, 0, 0) self._mapper = QtCore.QSignalMapper() QtCore.QObject.connect(self._mapper, QtCore.SIGNAL('mapped(const QString &)'), self.update_object)
def create_control(self, parent): """Creates the initial editor control.""" self.control = QtGui.QWidget() layout = QtGui.QGridLayout(self.control) layout.setContentsMargins(0, 0, 0, 0) self._mapper = QtCore.QSignalMapper() if is_pyside and QtCore.__version_info__ >= (5, 15): self._mapper.mappedString.connect(self.update_object) else: self._mapper.mapped[str].connect(self.update_object)
def init(self, parent): """ Finishes initializing the editor by creating the underlying toolkit widget. """ # Initialize the trait handler to use: trait_handler = self.factory.trait_handler if trait_handler is None: trait_handler = self.object.base_trait(self.name).handler self._trait_handler = trait_handler #Create a mapper to identify which icon button requested a contextmenu self.mapper = QtCore.QSignalMapper(self.control) self.delete_mapper = QtCore.QSignalMapper(self.control) # Create a widget with a grid layout as the container. self.control = QtGui.QWidget() self.control.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) layout = QtGui.QGridLayout(self.control) layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) layout.setContentsMargins(0, 0, 0, 0) # Remember the editor to use for each individual list item: editor = self.factory.editor if editor is None: editor = trait_handler.item_trait.get_editor() self._editor = getattr(editor, self.kind) # Set up the additional 'list items changed' event handler needed for # a list based trait. Note that we want to fire the update_editor_item # only when the items in the list change and not when intermediate # traits change. Therefore, replace "." by ":" in the extended_name # when setting up the listener. extended_name = self.extended_name.replace('.', ':') self.context_object.on_trait_change( self.update_editor_item, extended_name + '_items?', dispatch='ui') self.set_tooltip()
def init(self, parent): """ Finishes initializing the editor by creating the underlying toolkit widget. """ super(RadioEditor, self).init(parent) self.control = QtGui.QWidget() layout = QtGui.QGridLayout(self.control) layout.setContentsMargins(0, 0, 0, 0) self._mapper = QtCore.QSignalMapper() self._mapper.mapped.connect(self.update_object) self.rebuild_editor()
def init(self, parent): """ Finishes initializing the editor by creating the underlying toolkit widget. """ # Initialize the trait handler to use: trait_handler = self.factory.trait_handler if trait_handler is None: trait_handler = self.object.base_trait(self.name).handler self._trait_handler = trait_handler if self.scrollable: # Create a scrolled window to hold all of the list item controls: self.control = QtGui.QScrollArea() self.control.setFrameShape(QtGui.QFrame.NoFrame) self.control.setWidgetResizable(True) self._list_pane = QtGui.QWidget() else: self.control = QtGui.QWidget() self._list_pane = self.control self._list_pane.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding ) # Create a mapper to identify which icon button requested a contextmenu self.mapper = QtCore.QSignalMapper(self.control) # Create a widget with a grid layout as the container. layout = QtGui.QGridLayout(self._list_pane) layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) # Remember the editor to use for each individual list item: editor = self.factory.editor if editor is None: editor = trait_handler.item_trait.get_editor() self._editor = getattr(editor, self.kind) # Set up the additional 'list items changed' event handler needed for # a list based trait. Note that we want to fire the update_editor_item # only when the items in the list change and not when intermediate # traits change. Therefore, replace "." by ":" in the extended_name # when setting up the listener. extended_name = self.extended_name.replace(".", ":") self.context_object.on_trait_change( self.update_editor_item, extended_name + "_items?", dispatch="ui" ) self.set_tooltip()
def init(self, parent): """Finishes initializing the editor by creating the underlying toolkit widget. """ super().init(parent) self.control = QtGui.QWidget() layout = QtGui.QGridLayout(self.control) layout.setContentsMargins(0, 0, 0, 0) self._mapper = QtCore.QSignalMapper() if is_pyside and QtCore.__version_info__ >= (5, 15): self._mapper.mappedInt.connect(self.update_object) else: self._mapper.mapped.connect(self.update_object) self.rebuild_editor()
def create(self, parent): """ Create and set the toolkit-specific control that represents the pane. """ self.control = EditorAreaWidget(self, parent) self._filter = EditorAreaDropFilter(self) self.control.installEventFilter(self._filter) # Add shortcuts for scrolling through tabs. if sys.platform == "darwin": next_seq = "Ctrl+}" prev_seq = "Ctrl+{" else: next_seq = "Ctrl+PgDown" prev_seq = "Ctrl+PgUp" shortcut = QtGui.QShortcut(QtGui.QKeySequence(next_seq), self.control) shortcut.activated.connect(self._next_tab) self._connections_to_remove.append( (shortcut.activated, self._next_tab)) shortcut = QtGui.QShortcut(QtGui.QKeySequence(prev_seq), self.control) shortcut.activated.connect(self._previous_tab) self._connections_to_remove.append( (shortcut.activated, self._previous_tab)) # Add shortcuts for switching to a specific tab. mod = "Ctrl+" if sys.platform == "darwin" else "Alt+" mapper = QtCore.QSignalMapper(self.control) if is_pyside and is_qt6: mapper.mappedInt.connect(self._activate_tab) self._connections_to_remove.append( (mapper.mappedInt, self._activate_tab)) else: mapper.mapped.connect(self._activate_tab) self._connections_to_remove.append( (mapper.mapped, self._activate_tab)) for i in range(1, 10): sequence = QtGui.QKeySequence(mod + str(i)) shortcut = QtGui.QShortcut(sequence, self.control) shortcut.activated.connect(mapper.map) self._connections_to_remove.append( (shortcut.activated, mapper.map)) mapper.setMapping(shortcut, i - 1)
def color_editor_for(editor, parent): """ Creates a custom color editor panel for a specified editor. """ # Create the colour samples if it hasn't already been done. if len(color_samples) == 0: color_choices = (0, 128, 192, 255) for r in color_choices: for g in color_choices: for b in (0, 128, 255): color_samples.append(QtGui.QColor(r, g, b)) root = QtGui.QWidget() panel = QtGui.QHBoxLayout(root) panel.setContentsMargins(0, 0, 0, 0) swatch_editor = editor.factory.simple_editor(editor.ui, editor.object, editor.name, editor.description, None) swatch_editor.prepare(parent) panel.addWidget(swatch_editor.control) # Add all of the color choice buttons: grid = QtGui.QGridLayout() grid.setSpacing(0) mapper = QtCore.QSignalMapper(panel) rows = 4 cols = len(color_samples) // rows i = 0 sheet_template = """ QPushButton { min-height: 18px; max-height: 18px; min-width: 18px; max-width: 18px; background-color: rgb(%s); } """ for r in range(rows): for c in range(cols): control = FixedButton() color = color_samples[r * cols + c] color_text = "%d,%d,%d,%d" % color.getRgb() control.setStyleSheet(sheet_template % color_text) control.setAttribute(QtCore.Qt.WA_LayoutUsesWidgetRect, True) control.clicked.connect(mapper.map) mapper.setMapping(control, color_text) grid.addWidget(control, r, c) editor.set_tooltip(control) i += 1 mapper.mapped[str].connect(editor.update_object_from_swatch) panel.addLayout(grid) return root, swatch_editor
def update_editor(self): """ Updates the editor when the object trait changes externally to the editor. """ self.mapper = QtCore.QSignalMapper(self.control) self.delete_mapper = QtCore.QSignalMapper(self.control) # Disconnect the editor from any control about to be destroyed: self._dispose_items() layout = self.control.layout() # Create all of the list item trait editors: trait_handler = self._trait_handler resizable = ((trait_handler.minlen != trait_handler.maxlen) and self.mutable) item_trait = trait_handler.item_trait is_fake = (resizable and (len(self.value) == 0)) if is_fake: self.empty_list() else: # Asking the mapper to send the sender to the callback method self.mapper.mapped.connect(self.popup_menu) self.delete_mapper.mapped.connect(self._delete_item) editor = self._editor for index, value in enumerate(self.value): row, column = divmod(index, self.factory.columns) # Account for the fact that we have <columns> number of # pairs column = column * 2 if resizable: # Connecting the new button to the mapper control = IconButton('list_editor.png', self.popup_mapper.map) self.mapper.setMapping(control, index) layout.addWidget(control, row, column) if self.factory.deletable: # Connecting the new button to the mapper control = IconButton(QtGui.QStyle.SP_TitleBarCloseButton, self.delete_mapper.map) self.delete_mapper.setMapping(control, index) layout.addWidget(control, row, column) proxy = ListItemProxy(self.object, self.name, index, item_trait, value) if resizable: control.proxy = proxy peditor = editor(self.ui, proxy, 'value', self.description, self.control).set(object_name='') peditor.prepare(self.control) pcontrol = peditor.control pcontrol.proxy = proxy if isinstance(pcontrol, QtGui.QWidget): layout.addWidget(pcontrol, row, column + 1) else: layout.addLayout(pcontrol, row, column + 1)