コード例 #1
0
ファイル: menus.py プロジェクト: pombredanne/qthelpers
    def create(self, window: QtGui.QMainWindow, parent_menu: QtGui.QMenu):
        if self.disabled:
            return
        if callable(self.method_name):
            method = self.method_name
        else:
            method = getattr(window, self.method_name)

        if self.sep:
            parent_menu.addSeparator()
        if self.submenu:
            menu = QtGui.QMenu(self.verbose_name, p(parent_menu))
            if self.icon:
                action = parent_menu.addMenu(get_icon(self.icon), menu)
            else:
                action = parent_menu.addMenu(menu)
            action.hovered.connect(functools.partial(self.fill_submenu, window, menu, method))
        else:
            if self.icon:
                action = QtGui.QAction(get_icon(self.icon), self.verbose_name, p(parent_menu))
            else:
                action = QtGui.QAction(self.verbose_name, p(parent_menu))
            # noinspection PyUnresolvedReferences
            action.triggered.connect(method)
            parent_menu.addAction(action)
        if self.shortcut:
            action.setShortcut(self.shortcut)
        if self.help_text:
            action.setStatusTip(self.help_text)
コード例 #2
0
ファイル: forms.py プロジェクト: d9pouces/qthelpers
 def _fill_grid_layout(self, layout: QtGui.QGridLayout):
     """ Fill a QGridLayout with all MultiForms and Field, in the right order
     :param layout:
     :return:
     """
     all_components = []
     for multiform in self._multiforms.values():
         all_components.append(multiform)
     for field in self._fields.values():
         all_components.append(field)
     all_components.sort(key=self._sort_components)
     row_offset = layout.rowCount()
     for row_index, obj in enumerate(all_components):
         if isinstance(obj, MultiForm):  # a MultiForm already is a QWidget
             layout.addWidget(obj, row_offset + row_index, 0, 1, 2)
         elif isinstance(obj, SubForm):
             widget = QtGui.QGroupBox(str(obj.verbose_name), p(self))
             sub_layout = QtGui.QGridLayout(p(widget))
             obj._fill_grid_layout(sub_layout)
             widget.setLayout(sub_layout)
             layout.addWidget(widget, row_offset + row_index, 0, 1, 2)
         else:
             widget = obj.get_widget(self, self)
             self._widgets[obj.name] = widget
             obj.set_widget_value(widget, self._values[obj.name])
             if obj.label:
                 label = QtGui.QLabel(obj.label, p(self))
                 label.setDisabled(obj.disabled)
                 layout.addWidget(label, row_offset + row_index, 0)
             layout.addWidget(widget, row_offset + row_index, 1)
コード例 #3
0
ファイル: forms.py プロジェクト: d9pouces/qthelpers
 def _fill_form_layout(self, layout: QtGui.QFormLayout):
     """ Fill a QGridLayout with all MultiForms and Field, in the right order
     :param layout:
     :return:
     """
     all_components = []
     for multiform in self._multiforms.values():
         all_components.append(multiform)
     for field in self._fields.values():
         all_components.append(field)
     all_components.sort(key=self._sort_components)
     for row_index, obj in enumerate(all_components):
         if isinstance(obj, MultiForm):  # a MultiForm already is a QWidget
             layout.addRow(obj)
         elif isinstance(obj, SubForm):
             widget = QtGui.QGroupBox(str(obj.verbose_name), p(self))
             sub_layout = QtGui.QFormLayout(p(widget))
             obj._fill_form_layout(sub_layout)
             widget.setLayout(sub_layout)
             layout.addRow(widget)
         else:
             widget = obj.get_widget(self, self)
             self._widgets[obj.name] = widget
             obj.set_widget_value(widget, self._values[obj.name])
             layout.addRow(obj.label or '', widget)
コード例 #4
0
ファイル: fields.py プロジェクト: d9pouces/qthelpers
 def get_widget(self, field_group, parent=None):
     if self.verbose_name:
         editor = QtGui.QCheckBox(self.verbose_name, p(parent))
     else:
         editor = QtGui.QCheckBox(p(parent))
     if self.help_text:
         editor.setToolTip(self.help_text)
     editor.setDisabled(self.disabled)
     return editor
コード例 #5
0
ファイル: forms.py プロジェクト: d9pouces/qthelpers
 def __init__(self, initial=None, parent=None):
     QtGui.QGroupBox.__init__(self, p(parent))
     self._stacked_names = QtGui.QComboBox(p(self))
     # noinspection PyUnresolvedReferences
     self._stacked_names.currentIndexChanged.connect(self._change_widget)
     self._stacked_widget = QtGui.QStackedWidget(p(self))
     MultiForm.__init__(self, initial=initial)
     self.setTitle(str(self.verbose_name))
     self.setLayout(v_layout(self, self._stacked_names, self._stacked_widget))
コード例 #6
0
ファイル: docks.py プロジェクト: d9pouces/qthelpers
 def __init__(self, initial=None, parent=None):
     BaseForm.__init__(self, initial=initial)
     BaseDock.__init__(self, parent=p(parent))
     # widget creation
     widgets = []
     if self.description:
         widgets.append(QtGui.QLabel(self.description, p(self)))
     sub_layout = QtGui.QGridLayout(p(self))
     self._fill_grid_layout(layout=sub_layout)
     widgets.append(sub_layout)
     sub_widget = QtGui.QWidget(p(self))
     sub_widget.setLayout(v_layout(self, *widgets))
     self.setWidget(sub_widget)
コード例 #7
0
ファイル: windows.py プロジェクト: d9pouces/qthelpers
 def __init__(self, message, parent=None):
     super().__init__(p(parent))
     widgets = []
     if application.splashscreen_icon:
         pixmap = get_pixmap(application.splashscreen_icon)
         label = QtGui.QLabel(p(self))
         label.setPixmap(pixmap)
         widgets.append(label)
         edit = QtGui.QTextEdit(message, self)
         edit.setReadOnly(True)
         widgets.append(edit)
     widgets.append(create_button(_('Close'), min_size=True, parent=self, connect=self.close))
     self.setLayout(v_layout(self, *widgets))
コード例 #8
0
ファイル: fields.py プロジェクト: d9pouces/qthelpers
 def get_widget(self, field_group, parent=None):
     regexp = None
     if self.base_type == int:
         regexp = r'\d+(,\d+)*'
     elif self.base_type == float:
         regexp = r'(\?.\d+|\d+\.\d*)(,\?.\d+|,\d+\.\d)*'
     editor = QtGui.QLineEdit(p(parent))
     editor.setDisabled(self.disabled)
     if self.help_text is not None:
         editor.setToolTip(self.help_text)
     if regexp is not None:
         editor.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(regexp), p(parent)))
     return editor
コード例 #9
0
ファイル: fields.py プロジェクト: d9pouces/qthelpers
 def get_widget(self, field_group, parent=None):
     editor = QtGui.QLineEdit(p(parent))
     if self.help_text is not None:
         editor.setToolTip(self.help_text)
     editor.setValidator(self.widget_validator)
     editor.setDisabled(self.disabled)
     return editor
コード例 #10
0
ファイル: shortcuts.py プロジェクト: d9pouces/qthelpers
def __generic_layout(parent, layout, extra_args, args):
    for arg in args:
        if isinstance(arg, QtGui.QLayout):
            sub_widget = QtGui.QWidget(p(parent))
            sub_widget.setLayout(arg)
            layout.addWidget(sub_widget, *extra_args)
        elif isinstance(arg, QtGui.QWidget):
            layout.addWidget(arg, *extra_args)
    return layout
コード例 #11
0
ファイル: toolbars.py プロジェクト: d9pouces/qthelpers
 def create(self, window: QtGui.QMainWindow, parent: QtGui.QToolBar):
     if self.disabled:
         return
     if callable(self.method_name):
         method = self.method_name
     else:
         method = getattr(window, self.method_name)
     if self.sep:
         parent.addSeparator()
     if self.icon:
         action = QtGui.QAction(get_icon(self.icon), self.verbose_name, p(window))
     else:
         action = QtGui.QAction(self.verbose_name, p(window))
     # noinspection PyUnresolvedReferences
     action.triggered.connect(method)
     parent.addAction(action)
     if self.shortcut:
         action.setShortcut(self.shortcut)
     if self.help_text:
         action.setStatusTip(self.help_text)
コード例 #12
0
ファイル: widgets.py プロジェクト: pombredanne/qthelpers
 def __init__(self, filename: str = None, selection_filter: str = None, parent: QtGui.QWidget = None):
     self.selection_filter = selection_filter
     self.filename = None
     super().__init__(parent)
     self.select_button = create_button(
         _("Choose a file…"), min_size=True, connect=self.select_file, icon="edit-find"
     )
     self.line_editor = QtGui.QLineEdit(p(self))
     self.set_value(filename)
     layout = h_layout(self, self.select_button, self.line_editor)
     self.setLayout(layout)
     self.adjustSize()
コード例 #13
0
ファイル: widgets.py プロジェクト: pombredanne/qthelpers
    def select_file(self):
        try:
            from qthelpers.application import application

            dirname = application.GlobalInfos.last_open_folder
        except AttributeError:
            dirname = os.path.expanduser("~")
        # noinspection PyTypeChecker
        filename, selected_filter = QtGui.QFileDialog.getOpenFileName(
            p(self), _("Select a file"), dirname, self.selection_filter, "", 0
        )
        if filename:
            self.set_value(filename)
コード例 #14
0
ファイル: shortcuts.py プロジェクト: d9pouces/qthelpers
def create_button(legend: str='', icon: str=None, min_size: bool=False, connect=None, help_text: str=None,
                  flat: bool=False, parent=None, default=False):
    if isinstance(icon, str):
        button = QtGui.QPushButton(get_icon(icon), legend, p(parent))
    elif icon:
        button = QtGui.QPushButton(icon, legend, p(parent))
    else:
        button = QtGui.QPushButton(legend, p(parent))
    if min_size:
        size = button.minimumSizeHint()
        if not legend:
            size.setWidth(button.iconSize().width() + 4)
        button.setFixedSize(size)
    if help_text:
        button.setToolTip(help_text)
    if default:
        button.setDefault(True)
    button.setFlat(flat)
    if connect is not None:
        # noinspection PyUnresolvedReferences
        button.clicked.connect(connect)
    return button
コード例 #15
0
ファイル: forms.py プロジェクト: d9pouces/qthelpers
 def __init__(self, initial=None, parent=None):
     QtGui.QDialog.__init__(self, p(parent))
     BaseForm.__init__(self, initial=initial)
     ThreadedCalls.__init__(self)
     # widget creation
     widgets = []
     if self.description:
         widgets.append(QtGui.QLabel(self.description, p(self)))
     sub_layout = QtGui.QFormLayout(self)
     self._fill_form_layout(layout=sub_layout)
     widgets.append(sub_layout)
     self._buttons = []
     if self.text_confirm:
         self._buttons.append(create_button(self.text_confirm, connect=self.accept, min_size=True))
     if self.text_cancel:
         self._buttons.append(create_button(self.text_cancel, connect=self.reject, min_size=True))
     if self._buttons:
         widgets.append(h_layout(self, *self._buttons, direction=QtGui.QBoxLayout.RightToLeft))
     self.setLayout(v_layout(self, *widgets))
     if self.verbose_name:
         self.setWindowTitle(str(self.verbose_name))
     self.raise_()
コード例 #16
0
ファイル: shortcuts.py プロジェクト: d9pouces/qthelpers
def get_item(title: str, label: str, choices: list, initial: object=None) -> object:
    from qthelpers.fields import ChoiceField
    from qthelpers.forms import FormDialog

    class Dialog(FormDialog):
        verbose_name = title
        text_confirm = _('Select')
        value = ChoiceField(verbose_name=label, choices=choices, default=initial)

    values = Dialog.process(initial={'value': initial}, parent=p(None))
    if values is None:
        return None
    return values['value']
コード例 #17
0
ファイル: widgets.py プロジェクト: pombredanne/qthelpers
 def __init__(self, color: str = None, parent: QtGui.QWidget = None):
     self.color = None
     super().__init__(parent)
     self.select_button = create_button(
         _("Choose a color…"), min_size=True, connect=self.select_color, icon="preferences-color"
     )
     self.line_editor = QtGui.QLineEdit(p(self))
     self.line_editor.setValidator(self.validator)
     if not color or not COLOR_RE.match(color):
         color = None
     self.set_value(color)
     layout = h_layout(self, self.select_button, self.line_editor)
     self.setLayout(layout)
     self.adjustSize()
コード例 #18
0
ファイル: windows.py プロジェクト: d9pouces/qthelpers
 def base_set_sb_indicator(self, key, icon_name=None, message=None):
     if key not in self._indicators:
         label = QtGui.QLabel(p(self))
         statusbar = self.statusBar()
         """:type: QtGui.QStatusBar"""
         statusbar.insertPermanentWidget(len(self._indicators), label, 0)
         self._indicators[key] = label
     else:
         label = self._indicators[key]
         """:type: QtGui.Label"""
     if icon_name is not None:
         label.setPixmap(get_pixmap(icon_name))
     if message is not None:
         label.setText(message)
コード例 #19
0
ファイル: forms.py プロジェクト: d9pouces/qthelpers
 def __init__(self, initial: list=None, parent=None):
     """
     :param initial: initial values, as a dictionnary {field_name: field_value}
     """
     QtGui.QTreeWidget.__init__(self, p(parent))
     if initial is None:
         initial = []
     self._fields = {}
     item_count = len(initial)
     if self.min_number is not None:
         item_count = max(self.min_number, item_count)
     if self.max_number is not None:
         item_count = min(self.max_number, item_count)
     # noinspection PyUnusedLocal
     self._values = [{} for i in range(item_count)]
     fields = []
     for cls in self.__class__.__mro__:
         for field_name, field in cls.__dict__.items():
             if not isinstance(field, Field) or field_name in self._fields:
                 continue
             self._fields[field_name] = field
             field.name = field_name
             for index in range(item_count):  # get initial values
                 if index < len(initial):
                     self._values[index][field_name] = initial[index].get(field_name, field.default)
                 else:
                     self._values[index][field_name] = field.default
             fields.append((field.group_field_order, field_name))
     fields.sort()
     self._field_order = [f[1] for f in fields]
     headers = [self._fields[field_name].verbose_name for field_name in self._field_order]
     if self.show_remove_button:
         key = '1__'
         self._field_order.insert(0, key)
         headers.insert(0, '')
         self._fields[key] = ButtonField(connect=self.remove_item, legend='', icon='list-remove',
                                         verbose_name='', help_text=self.remove_help_text, default=None)
     if self.show_add_button:
         key = '0__'
         self._field_order.insert(0, key)
         headers.insert(0, '')
         self._fields[key] = ButtonField(connect=self.add_item, legend='', icon='list-add',
                                         verbose_name='', help_text=self.add_help_text, default=None)
     self.setIndentation(0)
     self.setHeaderLabels(headers)
     if not self.show_headers:
         self.header().close()
     for values in self._values:
         self.insert_item(values, index=None)
コード例 #20
0
ファイル: windows.py プロジェクト: d9pouces/qthelpers
 def base_save_document_as(self):
     # noinspection PyCallByClass
     (filename, selected_filter) = QtGui.QFileDialog.getSaveFileName(p(self), _('Please choose a name'),
                                                                     application.GlobalInfos.last_save_folder,
                                                                     filter=self.document_known_extensions)
     if not filename:
         return False
     application.GlobalInfos.last_save_folder = os.path.dirname(filename)
     self.current_document_filename = filename
     if self.save_document():
         self.current_document_is_modified = False
         self.base_window_title()
         self.base_add_recent_filename()
         return True
     return False
コード例 #21
0
ファイル: windows.py プロジェクト: d9pouces/qthelpers
 def base_open_document(self, filename=None):
     if self._base_check_is_modified():
         return False
     if not filename:
         # noinspection PyCallByClass
         (filename, selected_filter) = QtGui.QFileDialog.getOpenFileName(p(self), _('Please select a file'),
                                                                         application.GlobalInfos.last_open_folder,
                                                                         self.document_known_extensions)
         if not filename:
             return False
         application.GlobalInfos.last_open_folder = os.path.dirname(filename)
     if not self.is_valid_document(filename):
         warning(_('Invalid document'), _('Unable to open document %(filename)s.') %
                 {'filename': os.path.basename(filename)},
                 only_ok=True)
         return False
     self.unload_document()
     self.current_document_filename = filename
     self.current_document_is_modified = False
     self.base_window_title()
     self.base_add_recent_filename()
     self.load_document()
     return True
コード例 #22
0
ファイル: windows.py プロジェクト: d9pouces/qthelpers
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, p(parent))
        ThreadedCalls.__init__(self)

        self._window_id = next(BaseMainWindow._window_counter)
        self._docks = {}
        application.windows[self._window_id] = self

        # retrieve menus and associated actions from the whole class hierarchy
        menubar = self.menuBar()
        defined_qmenus = {}
        created_action_keys = set()
        supernames = [x.__name__.rpartition('.')[2] for x in self.__class__.__mro__]
        supernames.reverse()
        for menu_name in self.menus:
            defined_qmenus[menu_name] = menubar.addMenu(menu_name)
        for cls_name in supernames:
            for menu_name in registered_menus.get(cls_name, []):  # create all top-level menus
                if menu_name not in defined_qmenus:
                    defined_qmenus[menu_name] = menubar.addMenu(menu_name)
        supernames.reverse()
        for cls_name in supernames:
            for menu_action in registered_menu_actions.get(cls_name, []):
                if menu_action.uid in created_action_keys:  # skip overriden actions (there are already created)
                    continue
                created_action_keys.add(menu_action.uid)
                menu_action.create(self, defined_qmenus[menu_action.menu])

        # retrieve toolbar actions from the whole class hierarchy
        self.setUnifiedTitleAndToolBarOnMac(True)
        defined_qtoolbars = {}
        created_action_keys = set()
        for superclass in self.__class__.__mro__:
            cls_name = superclass.__name__.rpartition('.')[2]
            if cls_name not in registered_toolbars:
                continue
            for toolbar_name in registered_toolbars[cls_name]:  # create all top-level menus
                if toolbar_name not in defined_qtoolbars:
                    if toolbar_name is not None:
                        defined_qtoolbars[toolbar_name] = BaseToolBar(toolbar_name, p(self))
                    else:
                        defined_qtoolbars[toolbar_name] = BaseToolBar(_('Toolbar'), p(self))
                    self.addToolBar(defined_qtoolbars[toolbar_name])
            for toolbar_action in registered_toolbar_actions[cls_name]:
                if toolbar_action.uid in created_action_keys:  # skip overriden actions (there are already created)
                    continue
                created_action_keys.add(toolbar_action.uid)
                toolbar_action.create(self, defined_qtoolbars[toolbar_action.toolbar])

        # create all dock widgets
        for dock_cls in self.docks:
            """:type dock_cls: type"""
            if not isinstance(dock_cls, type) or not issubclass(dock_cls, BaseDock):
                continue
            dock = dock_cls(parent=self)
            """:type dock: BaseDock"""
            self._docks[dock_cls] = dock
            self.addDockWidget(dock.default_position, dock)
            menu_name = dock.menu
            if menu_name is not None:
                if menu_name not in defined_qmenus:
                    defined_qmenus[menu_name] = menubar.addMenu(menu_name)
                    connect = functools.partial(self._base_swap_dock_display, dock_cls)
                    action = MenuAction(connect, verbose_name=dock.verbose_name, menu=menu_name, shortcut=dock.shortcut)
                    action.create(self, defined_qmenus[menu_name])

        # some extra stuff
        self.setWindowTitle(self.verbose_name)
        if self.description_icon:
            self.setWindowIcon(get_icon(self.description_icon))

        self.setCentralWidget(self.central_widget())
        # restore state and geometry
        # noinspection PyBroadException
        self.adjustSize()
        try:
            cls_name = self.__class__.__name__
            if cls_name in application['GlobalInfos/main_window_geometries']:
                geometry_str = application['GlobalInfos/main_window_geometries'][cls_name].encode('utf-8')
                geometry = base64.b64decode(geometry_str)
                self.restoreGeometry(geometry)
            if cls_name in application['GlobalInfos/main_window_states']:
                state_str = application['GlobalInfos/main_window_states'][cls_name].encode('utf-8')
                state = base64.b64decode(state_str)
                self.restoreState(state)
        except ValueError:
            pass
        self.raise_()
コード例 #23
0
ファイル: docks.py プロジェクト: d9pouces/qthelpers
 def __init__(self, parent=None):
     QtGui.QDockWidget.__init__(self, str(self.verbose_name), p(parent))
     ThreadedCalls.__init__(self)
     self.parent_window = weakref.ref(parent)
     self.setObjectName(self.__class__.__name__)
コード例 #24
0
ファイル: fields.py プロジェクト: d9pouces/qthelpers
 def get_widget(self, field_group, parent=None):
     value = field_group
     connect = functools.partial(self.connect, value)
     return create_button(self.legend, icon=self.icon, min_size=True, flat=True, help_text=self.help_text,
                          connect=connect, parent=p(parent))
コード例 #25
0
ファイル: forms.py プロジェクト: d9pouces/qthelpers
 def __init__(self, initial=None, parent=None):
     BaseForm.__init__(self, initial=initial)
     QtGui.QWidget.__init__(self, p(parent))
     layout = QtGui.QGridLayout(p(parent))
     self._fill_grid_layout(layout)
     self.setLayout(layout)
コード例 #26
0
ファイル: fields.py プロジェクト: d9pouces/qthelpers
 def get_widget(self, field_group, parent=None):
     widget = QtGui.QComboBox(p(parent))
     for value, text_value in self.choices:
         widget.addItem(text_value, value)
     widget.setDisabled(self.disabled)
     return widget
コード例 #27
0
ファイル: forms.py プロジェクト: d9pouces/qthelpers
 def __init__(self, initial=None, parent=None):
     QtGui.QTabWidget.__init__(self, p(parent))
     MultiForm.__init__(self, initial=initial)
コード例 #28
0
ファイル: forms.py プロジェクト: d9pouces/qthelpers
 def __init__(self, initial=None, parent=None):
     QtGui.QToolBox.__init__(self, p(parent))
     MultiForm.__init__(self, initial=initial)
コード例 #29
0
ファイル: fields.py プロジェクト: d9pouces/qthelpers
 def get_widget(self, field_group, parent=None):
     button = Button(p(parent), self.connect, icon=self.icon, legend=self.legend, min_size=True, flat=True,
                     tooltip=self.help_text)
     button.args = [field_group]
     return button
コード例 #30
0
ファイル: fields.py プロジェクト: d9pouces/qthelpers
 def get_widget(self, field_group, parent=None):
     editor = QtGui.QLabel(p(parent))
     if self.help_text is not None:
         editor.setToolTip(self.help_text)
     return editor