def __init__(self, targetWidget, nodeName='font', defaultData=None): """ Constructor. :param targetWidget: a QWidget that must have a setFont() method For the (other) parameters see the AbstractCti constructor documentation. """ super(FontCti, self).__init__(nodeName, defaultData=QtGui.QFont() if defaultData is None else defaultData) self._targetWidget = targetWidget self.familyCti = self.insertChild( FontChoiceCti("family", defaultFamily=self.defaultData.family())) self.pointSizeCti = self.insertChild( IntCti("size", self.defaultData.pointSize(), minValue=1, maxValue=500, stepSize=1, suffix=' pt')) QtF = QtGui.QFont weights = [QtF.Light, QtF.Normal, QtF.DemiBold, QtF.Bold, QtF.Black] self.weightCti = self.insertChild( ChoiceCti("weight", defaultData=fontWeightIndex(self.defaultData, weights), displayValues=['Light', 'Normal', 'DemiBold', 'Bold', 'Black'], configValues=weights)) self.italicCti = self.insertChild(BoolCti("italic", self.defaultData.italic()))
def __init__(self, parent=None, msg="", title="Error"): super(MessageDisplay, self).__init__(parent=parent) self.layout = QtWidgets.QVBoxLayout() self.setLayout(self.layout) self.titleLabel = QtWidgets.QLabel(title) self.titleLabel.setTextFormat(Qt.PlainText) self.titleLabel.setTextInteractionFlags(Qt.TextSelectableByMouse) self.titleLabel.setAlignment(Qt.AlignHCenter) self.layout.addWidget(self.titleLabel, stretch=0) font = QtGui.QFont() font.setFamily(MONO_FONT) font.setFixedPitch(True) font.setPointSize(FONT_SIZE) self.messageLabel = QtWidgets.QLabel(msg) self.messageLabel.setFont(font) self.messageLabel.setTextFormat(Qt.PlainText) self.messageLabel.setTextInteractionFlags(Qt.TextSelectableByMouse) self.messageLabel.setWordWrap(True) self.messageLabel.setAlignment(Qt.AlignTop) self.messageLabel.setFrameStyle(QtWidgets.QFrame.Panel | QtWidgets.QFrame.Plain) self.layout.addWidget(self.messageLabel, stretch=1)
def __init__(self, textInspector, nodeName): """ Constructor :param textInspector: the TextInspector widget that is being configured :param nodeName: node name """ super(TextInspectorCti, self).__init__(nodeName) check_class(textInspector, TextInspector) self.textInspector = textInspector Opt = QtGui.QTextOption self.wordWrapCti = self.insertChild( ChoiceCti('word wrap', displayValues=[ 'No wrapping', 'Word boundaries', 'Anywhere', 'Boundaries or anywhere' ], configValues=[ Opt.NoWrap, Opt.WordWrap, Opt.WrapAnywhere, Opt.WrapAtWordBoundaryOrAnywhere ])) self.encodingCti = self.insertChild( ChoiceCti( 'encoding', editable=True, configValues=['utf-8', 'ascii', 'latin-1', 'windows-1252'])) self.fontCti = self.insertChild( FontCti(self.textInspector.editor, "font", defaultData=QtGui.QFont(MONO_FONT, FONT_SIZE)))
class MainGroupCti(GroupCti): """ Read only config Tree Item that only stores None. To be used as a high level group (e.g. the inspector group) Is the same as a groupCti but drawn as light text on a dark grey back ground """ _backgroundBrush = QtGui.QBrush( QtGui.QColor("#606060")) # create only once _foregroundBrush = QtGui.QBrush(QtGui.QColor(Qt.white)) # create only once _font = QtGui.QFont() _font.setWeight(QtGui.QFont.Bold) def __init__(self, nodeName, defaultData=None): """ Constructor. For the parameters see the AbstractCti constructor documentation. """ super(MainGroupCti, self).__init__(nodeName, defaultData, expanded=True) # always expand @property def font(self): """ Returns a font for displaying this item's text in the tree. """ return self._font @property def backgroundBrush(self): """ Returns a (dark gray) brush for drawing the background role in the tree. """ return self._backgroundBrush @property def foregroundBrush(self): """ Returns a (white) brush for drawing the foreground role in the tree. """ return self._foregroundBrush
def _nodeUnmarshall(self, data): """ Initializes itself non-recursively from data. Is called by unmarshall() """ qFont = QtGui.QFont() success = qFont.fromString(data) if not success: msg = "Unable to create QFont from string {!r}".format(data) logger.warning(msg) if DEBUGGING: raise ValueError(msg) self.data = qFont
def _nodeSetValuesFromDict(self, dct): """ Sets values from a dictionary in the current node. Non-recursive auxiliary function for setValuesFromDict """ if 'data' in dct: qFont = QtGui.QFont() success = qFont.fromString(dct['data']) if not success: msg = "Unable to create QFont from string {!r}".format(dct['data']) logger.warn(msg) if DEBUGGING: raise ValueError(msg) self.data = qFont
def _updateTargetFromNode(self): """ Applies the font config settings to the target widget's font. That is the targetWidget.setFont() is called with a font create from the config values. """ font = self.data if self.familyCti.configValue: font.setFamily(self.familyCti.configValue) else: font.setFamily(QtGui.QFont().family()) # default family font.setPointSize(self.pointSizeCti.configValue) font.setWeight(self.weightCti.configValue) font.setItalic(self.italicCti.configValue) self._targetWidget.setFont(font)
def __init__(self, parent=None): """ Constructor """ super(AboutDialog, self).__init__(parent=parent) self.setModal(True) mainLayout = QtWidgets.QVBoxLayout() self.setLayout(mainLayout) progVersionLabel = QtWidgets.QLabel() progVersionLabel.setText("{} {}{}".format( PROJECT_NAME, VERSION, ' (debugging-mode)' if DEBUGGING else '')) progVersionLabel.setTextInteractionFlags( QtCore.Qt.TextSelectableByMouse) mainLayout.addWidget(progVersionLabel) font = QtGui.QFont() font.setFamily(MONO_FONT) font.setFixedPitch(True) font.setPointSize(FONT_SIZE) self.editor = QtWidgets.QPlainTextEdit() self.editor.setReadOnly(True) self.editor.setFont(font) self.editor.setWordWrapMode(QtGui.QTextOption.NoWrap) self.editor.clear() self.editor.setPlainText("Retrieving package info...") mainLayout.addWidget(self.editor) self.progressLabel = QtWidgets.QLabel() mainLayout.addWidget(self.progressLabel) buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok) buttonBox.accepted.connect(self.accept) mainLayout.addWidget(buttonBox) self.resize(QtCore.QSize(800, 400))
def __init__(self, label, registry, parent=None): """ Constructor """ super(PluginsDialog, self).__init__(parent=parent) check_class(registry, BaseRegistry) self._label = label self._orgRegistry = registry self._registry = copy.deepcopy(registry) # make copy so changes can be canceled self._tableModel = self._registry.createTableModel(parent=self) self.mapper = QtWidgets.QDataWidgetMapper(parent=self) self.mapper.setModel(self._tableModel) self.setWindowTitle("Argos {} Plugins".format(label)) layout = QtWidgets.QVBoxLayout(self) self.verSplitter = QtWidgets.QSplitter(Qt.Vertical) #self.verSplitter.setCollapsible(1, False) self.verSplitter.setChildrenCollapsible(False) layout.addWidget(self.verSplitter) self.tableWidget = TableEditWidget(self._tableModel) self.verSplitter.addWidget(self.tableWidget) self._tableView = self.tableWidget.tableView self._tableView.installEventFilter(self) # Form self.horSplitter = QtWidgets.QSplitter(Qt.Horizontal) self.horSplitter.setChildrenCollapsible(False) self.verSplitter.addWidget(self.horSplitter) self.formWidget = QtWidgets.QWidget() self.formLayout = QtWidgets.QFormLayout() self.formLayout.setContentsMargins(0, 0, 0, 0) self.formWidget.setLayout(self.formLayout) self.horSplitter.addWidget(self.formWidget) self._editWidgets = [] itemCls = registry.ITEM_CLASS assert len(itemCls.LABELS) == len(itemCls.TYPES), \ "Regtype Mismatch: {} != {}".format(len(itemCls.LABELS), len(itemCls.TYPES)) for col, (label, regType) in enumerate(zip(itemCls.LABELS, itemCls.TYPES)): if regType == RegType.String: editWidget = QtWidgets.QLineEdit() self.mapper.addMapping(editWidget, col) elif regType == RegType.ShortCut: editWidget = ShortCutEditor() self.mapper.addMapping(editWidget, col) elif regType == RegType.ColorStr: editWidget = ColorSelectWidget() self.mapper.addMapping(editWidget.lineEditor, col) else: raise AssertionError("Unexpected regType: {}".format(regType)) editWidget.installEventFilter(self) self.formLayout.addRow(label, editWidget) self._editWidgets.append(editWidget) # Detail info widget font = QtGui.QFont() font.setFamily(MONO_FONT) font.setFixedPitch(True) font.setPointSize(FONT_SIZE) self.editor = QtWidgets.QTextEdit() self.editor.setReadOnly(True) #self.editor.setFocusPolicy(Qt.NoFocus) # Allow focus so that user can copy text from it. #self.editor.setFont(font) self.editor.setWordWrapMode(QtGui.QTextOption.WordWrap) self.editor.clear() self.horSplitter.addWidget(self.editor) self.horSplitter.setStretchFactor(0, 2) self.horSplitter.setStretchFactor(1, 3) self.verSplitter.setSizes([300, 150]) # Reset/Cancel/Save Buttons self.saveButton = QtWidgets.QPushButton("Save") self.saveButton.clicked.connect(self.accept) self.cancelButton = QtWidgets.QPushButton("Cancel") self.cancelButton.clicked.connect(self.reject) self.resetButton = QtWidgets.QPushButton("Reset Table to Defaults...") self.resetButton.clicked.connect(self.resetToDefaults) self.resetButton.setIcon(QtGui.QIcon(os.path.join(icons_directory(), 'reset-l.svg'))) # We use a button layout instead of a QButtonBox because there always will be a default # button (e.g. the Save button) that will light up, even if another widget has the focus. # From https://doc.qt.io/archives/qt-4.8/qdialogbuttonbox.html#details # However, if there is no default button set and to preserve which button is the default # button across platforms when using the QPushButton::autoDefault property, the first # push button with the accept role is made the default button when the QDialogButtonBox # is shown, self.buttonLayout = QtWidgets.QHBoxLayout() self.buttonLayout.addWidget(self.resetButton) self.buttonLayout.addStretch() if sys.platform == 'darwin': self.buttonLayout.addWidget(self.cancelButton) self.buttonLayout.addWidget(self.saveButton) else: self.buttonLayout.addWidget(self.saveButton) self.buttonLayout.addWidget(self.cancelButton) layout.addLayout(self.buttonLayout) # Connect signals and populate self.tableWidget.tableView.selectionModel().currentChanged.connect(self.currentItemChanged) self.tableWidget.tableView.model().sigItemChanged.connect(self._updateEditor) self.resize(QtCore.QSize(1100, 700)) self.tableWidget.tableView.setFocus(Qt.NoFocusReason) self.tryImportAllPlugins()
def _enforceDataType(self, data): """ Converts to str so that this CTI always stores that type. """ result = QtGui.QFont(data) return result
def __init__(self, tableInspector, nodeName): super(TableInspectorCti, self).__init__(nodeName) check_class(tableInspector, TableInspector) self.tableInspector = tableInspector # The defaultRowHeightCti and defaultColWidthCti are initialized with -1; they will get # the actual values in the TableInspector constructor. self.autoRowHeightCti = self.insertChild( BoolCti("auto row heights", False, childrenDisabledValue=True)) self.defaultRowHeightCti = self.autoRowHeightCti.insertChild( IntCti("row height", -1, minValue=20, maxValue=500, stepSize=5)) self.autoColWidthCti = self.insertChild( BoolCti("auto column widths", False, childrenDisabledValue=True)) self.defaultColWidthCti = self.autoColWidthCti.insertChild( IntCti("column width", -1, minValue=20, maxValue=500, stepSize=5)) self.insertChild(BoolCti("separate fields", True)) self.insertChild(BoolCti("word wrap", False)) self.encodingCti = self.insertChild( ChoiceCti( 'encoding', editable=True, configValues=['utf-8', 'ascii', 'latin-1', 'windows-1252'])) fmtCti = self.insertChild(GroupCti("format specifiers")) # Use '!r' as default for Python 2. This will convert the floats with repr(), which is # necessary because str() or an empty format string will only print 2 decimals behind the # point. In Python 3 this is not necessary: all relevant decimals are printed. numDefaultValue = 6 if six.PY2 else 0 self.strFormatCti = fmtCti.insertChild( ChoiceCti("strings", 0, editable=True, completer=None, configValues=[ '', 's', '!r', '!a', '10.10s', '_<15s', '_>15s', "'str: {}'" ])) self.intFormatCti = fmtCti.insertChild( ChoiceCti("integers", 0, editable=True, completer=None, configValues=[ '', 'd', 'n', 'c', '#b', '#o', '#x', '!r', '8d', '#8.4g', '_<10', '_>10', "'int: {}'" ])) self.numFormatCti = fmtCti.insertChild( ChoiceCti("other numbers", numDefaultValue, editable=True, completer=None, configValues=[ '', 'f', 'g', 'n', '%', '!r', '8.3e', '#8.4g', '_<15', '_>15', "'num: {}'" ])) self.otherFormatCti = fmtCti.insertChild( ChoiceCti("other types", 0, editable=True, completer=None, configValues=['', '!s', '!r', "'other: {}'"])) self.maskFormatCti = fmtCti.insertChild( ChoiceCti("missing data", 2, editable=True, completer=None, configValues=['', "' '", "'--'", "'<masked>'", '!r'])) self.fontCti = self.insertChild( FontCti(self.tableInspector, "font", defaultData=QtGui.QFont(MONO_FONT, FONT_SIZE))) self.dataColorCti = self.insertChild( ColorCti('text color', QtGui.QColor('#000000'))) self.missingColorCti = self.insertChild( ColorCti('missing data color', QtGui.QColor('#B0B0B0'))) self.horAlignCti = self.insertChild( ChoiceCti( 'horizontal alignment', configValues=[ ALIGN_SMART, Qt.AlignLeft, Qt.AlignHCenter, Qt.AlignRight ], displayValues=['Type-dependent', 'Left', 'Center', 'Right'])) # Qt.AlignJustify not included, it doesn't seem to do anything, self.verAlignCti = self.insertChild( ChoiceCti( 'vertical alignment', defaultData=1, configValues=[Qt.AlignTop, Qt.AlignVCenter, Qt.AlignBottom], displayValues=['Top', 'Center', 'Bottom'])) # Per pixel scrolling works better for large cells (e.g. containing XML strings). self.insertChild( ChoiceCti("scroll", displayValues=["Per cell", "Per pixel"], configValues=[ QtWidgets.QAbstractItemView.ScrollPerItem, QtWidgets.QAbstractItemView.ScrollPerPixel ]))
def __init__(self, registry, parent=None, attrNames=None, headerNames=None, headerSizes=None, onlyShowImported=False, importOnSelect=True): """ Constructor. If onlyShowImported is True, regItems that are not (successfully) imported are filtered from the table. By default onlyShowImported is False. If importOnSelect is True (the default), the item is imported if the user selects it. """ super(RegistryTab, self).__init__(parent=parent) self._importOnSelect = importOnSelect self._onlyShowImported = onlyShowImported self._registry = registry attrNames = [] if attrNames is None else attrNames headerNames = attrNames if headerNames is None else headerNames headerSizes = [] if headerSizes is None else headerSizes if headerSizes is None: headerSizes = [] else: assert len(headerSizes) == len(attrNames), \ "Size mismatch {} != {}".format(len(headerSizes), len(attrNames)) layout = QtWidgets.QVBoxLayout(self) statusLayout = QtWidgets.QHBoxLayout() layout.addLayout(statusLayout) self.statusLabel = QtWidgets.QLabel("") statusLayout.addWidget(self.statusLabel) statusLayout.setStretch(0, 1) self.loadAllButton = QtWidgets.QPushButton("Load all") self.loadAllButton.setFocusPolicy(Qt.ClickFocus) self.loadAllButton.clicked.connect(self.tryImportAllPlugins) statusLayout.addWidget(self.loadAllButton) statusLayout.setStretch(1, 0) splitter = QtWidgets.QSplitter(Qt.Vertical) layout.addWidget(splitter) # Table tableModel = RegistryTableModel(self._registry, attrNames=attrNames, parent=self) proxyTableModel = RegistryTableProxyModel(parent=self, onlyShowImported=self._onlyShowImported) proxyTableModel.setSourceModel(tableModel) self.tableView = RegistryTableView(proxyTableModel, onlyShowImported=self.onlyShowImported) tableHeader = self.tableView.horizontalHeader() for col, headerSize in enumerate(headerSizes): if headerSize: tableHeader.resizeSection(col, headerSize) selectionModel = self.tableView.selectionModel() selectionModel.currentRowChanged.connect(self.currentItemChanged) splitter.addWidget(self.tableView) splitter.setCollapsible(0, False) # Detail info widget font = QtGui.QFont() font.setFamily(MONO_FONT) font.setFixedPitch(True) font.setPointSize(FONT_SIZE) self.editor = QtWidgets.QTextEdit() self.editor.setReadOnly(True) self.editor.setFont(font) self.editor.setWordWrapMode(QtGui.QTextOption.NoWrap) self.editor.clear() splitter.addWidget(self.editor) splitter.setCollapsible(1, False) splitter.setSizes([300, 150]) self.tableView.setFocus(Qt.NoFocusReason)