def headerData(self, section, orientation, role): """ Public method to get header data from the model. @param section section number (integer) @param orientation orientation (Qt.Orientation) @param role role of the data to retrieve (integer) @return requested data """ if role == Qt.SizeHintRole: fm = QFontMetrics(QFont()) height = fm.height() + fm.height() // 3 width = \ fm.width(self.headerData(section, orientation, Qt.DisplayRole)) return QSize(width, height) if orientation == Qt.Horizontal: if role == Qt.DisplayRole: try: return self.__headers[section] except IndexError: return None return None return QAbstractTableModel.headerData(self, section, orientation, role)
def __init__(self, name, currentValue): super(QDialog, self).__init__() self.setWindowTitle(name) self.resize(800, 600) self.codeEdit = QsciScintilla() self.codeEdit.setText(currentValue) fixedWidthFont = QFontDatabase.systemFont(QFontDatabase.FixedFont) self.codeEdit.setFont(fixedWidthFont) fontmetrics = QFontMetrics(fixedWidthFont) self.codeEdit.setMarginWidth(0, fontmetrics.width("000")) self.codeEdit.setMarginLineNumbers(0, True) self.codeEdit.setMarginsBackgroundColor(QColor("#cccccc")) self.codeEdit.setBraceMatching(QsciScintilla.SloppyBraceMatch) self.codeEdit.setCaretLineVisible(True) self.codeEdit.setCaretLineBackgroundColor(QColor("#ffe4e4")) lexer = QsciLexerPython() lexer.setDefaultFont(fixedWidthFont) self.codeEdit.setLexer(lexer) self.codeEdit.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0) self.codeEdit.setUtf8(True) self.codeEdit.setTabWidth(4) self.codeEdit.setIndentationsUseTabs(True) self.codeEdit.setIndentationGuides(True) self.codeEdit.setTabIndents(True) self.codeEdit.setAutoIndent(True) self.cancelButton = QPushButton('Cancel') self.cancelButton.clicked.connect(self.cancel) self.acceptButton = QPushButton('Accept') self.acceptButton.clicked.connect(self.accept) self.pythonButton = QRadioButton('Python') self.pythonButton.setChecked(True) self.pythonButton.clicked.connect(self.pythonClicked) self.cppButton = QRadioButton('C++') self.cppButton.clicked.connect(self.cppClicked) hLayout0 = QHBoxLayout() hLayout0.addWidget(self.pythonButton) hLayout0.addWidget(self.cppButton) container0 = QWidget() container0.setLayout(hLayout0) verticalLayout = QVBoxLayout() verticalLayout.addWidget(container0) verticalLayout.addWidget(self.codeEdit) container = QWidget() hLayout =QHBoxLayout() hLayout.addWidget(self.cancelButton) hLayout.addWidget(self.acceptButton) container.setLayout(hLayout) verticalLayout.addWidget(container) self.setLayout(verticalLayout) self.language = 'python'
def __init__(self, settings): super(QWidget, self).__init__() self._layout = QBoxLayout(QBoxLayout.TopToBottom) self.setLayout(self._layout) self.settings = settings # eq directory widget = QWidget() layout = QBoxLayout(QBoxLayout.LeftToRight) widget.setLayout(layout) label = QLabel("Everquest Directory: ") layout.addWidget(label) text = QLineEdit() text.setText(self.settings.get_value("general", "eq_directory")) text.setToolTip(self.settings.get_value("general", "eq_directory")) text.setDisabled(True) self._text_eq_directory = text layout.addWidget(text, 1) button = QPushButton("Browse...") button.clicked.connect(self._get_eq_directory) layout.addWidget(button) self._layout.addWidget(widget, 0, Qt.AlignTop) # eq directory info frame = QFrame() frame.setFrameShadow(QFrame.Sunken) frame.setFrameShape(QFrame.Box) frame_layout = QBoxLayout(QBoxLayout.LeftToRight) frame.setLayout(frame_layout) widget = QWidget() layout = QBoxLayout(QBoxLayout.LeftToRight) widget.setLayout(layout) self._label_eq_directory = QLabel() layout.addWidget(self._label_eq_directory, 1) frame_layout.addWidget(widget, 1, Qt.AlignCenter) self._layout.addWidget(frame, 1) # parse interval widget = QWidget() layout = QBoxLayout(QBoxLayout.LeftToRight) widget.setLayout(layout) label = QLabel("Seconds between parse checks: ") layout.addWidget(label, 0, Qt.AlignLeft) text = QLineEdit() text.setText(str(self.settings.get_value("general", "parse_interval"))) text.editingFinished.connect(self._parse_interval_editing_finished) text.setMaxLength(3) self._text_parse_interval = text metrics = QFontMetrics(QApplication.font()) text.setFixedWidth(metrics.width("888888")) layout.addWidget(text, 0, Qt.AlignLeft) self._layout.addWidget(widget, 0, Qt.AlignTop | Qt.AlignLeft) # spacing at bottom of window widget = QWidget() self._layout.addWidget(widget, 1) # setup if settings.get_value("general", "eq_directory") is not None: self._check_directory_stats()
def updateRects_v2(self, option, index): margin = self.margin * 2 iconSize = max(24 * self.factor, 18) item = index.internalPointer() fm = QFontMetrics(option.font) h = fm.lineSpacing() self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin) top = 15 * self.factor self.topRect = QRect(self.itemRect) self.topRect.setHeight(top) self.cardRect = QRect(self.itemRect.topLeft() + QPoint(0, top), self.itemRect.bottomRight()) self.iconRect = QRect(self.cardRect.topLeft() + QPoint(margin, margin), QSize(iconSize, iconSize)) self.labelRect = QRect(self.cardRect.topRight() - QPoint(margin + self.factor * 18, 1), self.cardRect.topRight() + QPoint(- margin - self.factor * 4, self.factor * 24)) self.titleRect = QRect(self.iconRect.topRight() + QPoint(margin, 0), self.labelRect.bottomLeft() - QPoint(margin, margin)) self.titleRect.setBottom(self.iconRect.bottom()) self.mainRect = QRect(self.iconRect.bottomLeft() + QPoint(0, margin), self.cardRect.bottomRight() - QPoint(margin, 2*margin)) self.mainRect.setLeft(self.titleRect.left()) self.mainLineRect = QRect(self.mainRect.topLeft(), self.mainRect.topRight() + QPoint(0, h)) self.mainTextRect = QRect(self.mainLineRect.bottomLeft() + QPoint(0, margin), self.mainRect.bottomRight()) if not item.data(Outline.summarySentence): self.mainTextRect.setTopLeft(self.mainLineRect.topLeft())
def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(ZoomValuesDialog, self).__init__(parent) self.setupUi(self) self.removeButton.clicked.connect( self.zoomValuesTable.removeSelected) self.removeAllButton.clicked.connect(self.zoomValuesTable.removeAll) import Helpviewer.HelpWindow from .ZoomValuesModel import ZoomValuesModel self.zoomValuesTable.verticalHeader().hide() self.__zoomValuesModel = ZoomValuesModel( Helpviewer.HelpWindow.HelpWindow.zoomManager(), self) self.__proxyModel = QSortFilterProxyModel(self) self.__proxyModel.setSourceModel(self.__zoomValuesModel) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.zoomValuesTable.setModel(self.__proxyModel) fm = QFontMetrics(QFont()) height = fm.height() + fm.height() // 3 self.zoomValuesTable.verticalHeader().setDefaultSectionSize(height) self.zoomValuesTable.verticalHeader().setMinimumSectionSize(-1) self.__calculateHeaderSizes()
def draw_indicator(indicator: int): pixmap = QPixmap(24, 24) painter = QPainter(pixmap) w, h = pixmap.width(), pixmap.height() painter.fillRect(0, 0, w, h, QBrush((QColor(0, 0, 200, 255)))) pen = QPen(QColor("white")) pen.setWidth(2) painter.setPen(pen) font = util.get_monospace_font() font.setBold(True) font.setPixelSize(16) painter.setFont(font) f = QFontMetrics(painter.font()) indicator_str = str(indicator) if indicator < 10 else "+" fw = f.width(indicator_str) fh = f.height() painter.drawText(math.ceil(w / 2 - fw / 2), math.ceil(h / 2 + fh / 4), indicator_str) painter.end() return QIcon(pixmap)
def __init__(self, parent=None): super().__init__(parent) QPixmapCache.setCacheLimit(app_constants.THUMBNAIL_CACHE_SIZE[0]* app_constants.THUMBNAIL_CACHE_SIZE[1]) self._painted_indexes = {} #misc.FileIcon.refresh_default_icon() self.file_icons = misc.FileIcon() if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() self.font_size = app_constants.GALLERY_FONT[1] self.font_name =0 # app_constants.GALLERY_FONT[0] if not self.font_name: self.font_name = QWidget().font().family() self.title_font = QFont() self.title_font.setBold(True) self.title_font.setFamily(self.font_name) self.artist_font = QFont() self.artist_font.setFamily(self.font_name) if self.font_size is not 0: self.title_font.setPixelSize(self.font_size) self.artist_font.setPixelSize(self.font_size) self.title_font_m = QFontMetrics(self.title_font) self.artist_font_m = QFontMetrics(self.artist_font) t_h = self.title_font_m.height() a_h = self.artist_font_m.height() self.text_label_h = a_h + t_h * 2 self.W = app_constants.THUMB_W_SIZE self.H = app_constants.THUMB_H_SIZE + app_constants.GRIDBOX_LBL_H#self.text_label_h #+ app_constants.GRIDBOX_LBL_H
def data(self, index, role=Qt.EditRole): level = 0 i = index while i.parent() != QModelIndex(): i = i.parent() level += 1 if role == Qt.BackgroundRole: if level == 0: return QBrush(lightBlue()) if role == Qt.TextAlignmentRole: if level == 0: return Qt.AlignCenter if role == Qt.FontRole: if level in [0, 1]: f = qApp.font() f.setBold(True) return f if role == Qt.ForegroundRole: if level == 0: return QBrush(Qt.darkBlue) if role == Qt.SizeHintRole: fm = QFontMetrics(qApp.font()) h = fm.height() if level == 0: return QSize(0, h + 12) elif level == 1: return QSize(0, h + 6) return QStandardItemModel.data(self, index, role)
def __init__(self, parent): super().__init__(parent) pvMet = QFontMetrics(self.font()) pvLineHeight = pvMet.height() self.setMaximumHeight(pvLineHeight * 12) self.setMinimumHeight(pvLineHeight * 12) self.setWordWrap(True)
def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(UserAgentsDialog, self).__init__(parent) self.setupUi(self) self.removeButton.clicked.connect( self.userAgentsTable.removeSelected) self.removeAllButton.clicked.connect( self.userAgentsTable.removeAll) self.userAgentsTable.verticalHeader().hide() self.__userAgentModel = UserAgentModel( Helpviewer.HelpWindow.HelpWindow.userAgentsManager(), self) self.__proxyModel = QSortFilterProxyModel(self) self.__proxyModel.setSourceModel(self.__userAgentModel) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.userAgentsTable.setModel(self.__proxyModel) fm = QFontMetrics(QFont()) height = fm.height() + fm.height() // 3 self.userAgentsTable.verticalHeader().setDefaultSectionSize(height) self.userAgentsTable.verticalHeader().setMinimumSectionSize(-1) self.userAgentsTable.resizeColumnsToContents() self.userAgentsTable.horizontalHeader().setStretchLastSection(True)
def __init__(self, text, parent): super(DragLabel, self).__init__(parent) metric = QFontMetrics(self.font()) size = metric.size(Qt.TextSingleLine, text) image = QImage(size.width() + 12, size.height() + 12, QImage.Format_ARGB32_Premultiplied) image.fill(qRgba(0, 0, 0, 0)) font = QFont() font.setStyleStrategy(QFont.ForceOutline) painter = QPainter() painter.begin(image) painter.setRenderHint(QPainter.Antialiasing) painter.setBrush(Qt.white) painter.drawRoundedRect(QRectF(0.5, 0.5, image.width() - 1, image.height() - 1), 25, 25, Qt.RelativeSize) painter.setFont(font) painter.setBrush(Qt.black) painter.drawText(QRect(QPoint(6, 6), size), Qt.AlignCenter, text) painter.end() self.setPixmap(QPixmap.fromImage(image)) self.labelText = text
def __init__(self, parent=None): super(QMainWindow,self).__init__() #--------------------------------------------------------------- statusWin = QLabel(self) #statusWin = QPlainTextEdit(self) # status window #statusWin.appendHtml("<b>hallo<br>hallo2<br>hallo3</b>") tabWin = TabWidgets(self) # tabbed window print('hint status win: {0}'.format(statusWin.sizeHint())) print('hint_tab win: {0}'.format(tabWin.sizeHint())) print('hint main win: {0}'.format(self.sizeHint())) mSize = QFontMetrics(statusWin.font()) rowHt = mSize.lineSpacing() # fixed height for statusWin needed as the sizeHint of tabWin is very small #statusWin.setFixedHeight(4*rowHt+4) # add status window underneath plot Tab Widgets: spltVMain = QSplitter(QtCore.Qt.Vertical) spltVMain.addWidget(tabWin) spltVMain.addWidget(statusWin) # relative initial sizes of subwidgets, this doesn't work here # spltVMain.setStretchFactor(4,1) spltVMain.setSizes([statusWin.sizeHint().height()*2, statusWin.sizeHint().height()*0.05]) spltVMain.setFocus() # make spltVMain occupy the main area of QMainWindow and set inheritance self.setCentralWidget(spltVMain) print('size tabs: {0}'.format(tabWin.size())) print('size status: {0}'.format(statusWin.size())) print('size self: {0}'.format(self.size()))
def paintEvent(self, event): """QLineEdit.paintEvent implementation. Draws prompt """ QLineEdit.paintEvent(self, event) if self._promptText and not self.text() and self.isEnabled(): option = QStyleOptionFrameV3() self.initStyleOption(option) left, top, right, bottom = self.getTextMargins() va = self.style().visualAlignment(self.layoutDirection(), self.alignment()) rect = ( self.style() .subElementRect(QStyle.SE_LineEditContents, option, self) .adjusted(2, 0, 0, 0) .adjusted(left, top, -right, -bottom) ) fm = QFontMetrics(self.font()) text = fm.elidedText(self._promptText, Qt.ElideRight, rect.width()) painter = QPainter(self) painter.setPen(self.palette().color(QPalette.Disabled, QPalette.Text)) painter.drawText(rect, va, text)
def paint(self, painter, option, index): extra = index.data(Qt.UserRole + 1) if not extra: return QStyledItemDelegate.paint(self, painter, option, index) else: if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight)) title = index.data() extra = " - {}".format(extra) painter.drawText(option.rect, Qt.AlignLeft, title) fm = QFontMetrics(option.font) w = fm.width(title) r = QRect(option.rect) r.setLeft(r.left() + w) painter.save() if option.state & QStyle.State_Selected: painter.setPen(QColor(S.highlightedTextLight)) else: painter.setPen(QColor(S.textLight)) painter.drawText(r, Qt.AlignLeft, extra) painter.restore()
def __init__(self, parent=None): super(CodeEditor, self).__init__(parent) self.numArea = LineNumArea(self) # Binding signals to slots self.blockCountChanged.connect(self.updateNumWidth) self.updateRequest.connect(self.updateNum) self.cursorPositionChanged.connect(self.highlightLine) self.textChanged.connect(self.highlightCode) # editor config font = QFont() font.setFamily("Courier") font.setStyleHint(QFont.Monospace) font.setFixedPitch(True) font.setPointSize(12) self.setFont(font) metrics = QFontMetrics(font) self.setTabStopWidth(4 * metrics.width('a')) # tab width # highlighter self.highlighter = Highlighter(self.document()) # init self.updateNumWidth(0) self.highlightLine()
def sizeHint(self, option, index): """ Public method to get a size hint for the specified list item. @param option style option used for painting (QStyleOptionViewItem) @param index model index of the item (QModelIndex) @return size hint (QSize) """ if not self.__rowHeight: opt = QStyleOptionViewItem(option) self.initStyleOption(opt, index) widget = opt.widget style = widget.style() if widget is not None \ else QApplication.style() padding = style.pixelMetric(QStyle.PM_FocusFrameHMargin) + 1 titleFont = opt.font titleFont.setBold(True) titleFont.setPointSize(titleFont.pointSize() + 1) self.__padding = padding \ if padding > GreaseMonkeyConfigurationListDelegate.MinPadding \ else GreaseMonkeyConfigurationListDelegate.MinPadding titleMetrics = QFontMetrics(titleFont) self.__rowHeight = 2 * self.__padding + \ opt.fontMetrics.leading() + \ opt.fontMetrics.height() + \ titleMetrics.height() return QSize(GreaseMonkeyConfigurationListDelegate.ItemWidth, self.__rowHeight)
def text(self, text: str, pos: QRectF, color: QColor=None, size: int=20, shaded: int=0, bold: bool=False,shrinkToFit=10) -> None: if not isinstance(text,str): text = "{}".format(text) self._font.setPointSize(size) if bold: self._font.setWeight(QFont.Black) else: self._font.setWeight(QFont.Bold) self._painter.setFont(self._font) fm = QFontMetrics(self._font) if pos.width() == 0: pos.setWidth(fm.width(text)) if pos.height() == 0: pos.setHeight(fm.height()) if size > shrinkToFit: # if fm.width(text) > pos.width() or fm.height() > pos.height()+2: self.text(text,pos,color,size-1,shaded,bold,shrinkToFit) return if shaded: diff = size//4 if isinstance(shaded,bool) and shaded == True else shaded self._painter.setPen(self._fgs) pos2 = pos.translated(diff, diff) self._painter.drawText(pos2, Qt.AlignCenter, text) p = QPen(color if color is not None else self._fg) self._painter.setPen(p) self._painter.drawText(pos, Qt.AlignCenter, text)
def _paintLabel(self, label, xpos, ypos, painter): """ """ fm = QFontMetrics(self._font) frect = fm.boundingRect(label) if self._orientation == Qt.Horizontal: pos = xpos lenght = frect.width() / 2 + frect.width() / 10 else: pos = ypos lenght = (frect.height() / 2) - fm.descent() if pos > self._scaleLenght() - lenght: pos = self._scaleLenght() - lenght elif pos <= 0: pos = 0 if self._orientation == Qt.Horizontal: if pos >= lenght: pos = pos - lenght painter.drawText( QPoint(pos, ypos), label ) else: if pos == 0: pos = lenght*2 else: pos = pos + lenght painter.drawText( QPoint(xpos+2, pos), label )
def createTab(self, fileName): self.previewBlocked = False self.editBoxes.append(ReTextEdit(self)) self.highlighters.append(ReTextHighlighter(self.editBoxes[-1].document())) if enchant_available and self.actionEnableSC.isChecked(): self.highlighters[-1].dictionary = \ enchant.Dict(self.sl) if self.sl else enchant.Dict() self.highlighters[-1].rehighlight() if globalSettings.useWebKit: self.previewBoxes.append(self.getWebView()) else: self.previewBoxes.append(QTextBrowser()) self.previewBoxes[-1].setOpenExternalLinks(True) self.previewBoxes[-1].setVisible(False) self.fileNames.append(fileName) markupClass = self.getMarkupClass(fileName) self.markups.append(self.getMarkup(fileName)) self.highlighters[-1].docType = (markupClass.name if markupClass else '') liveMode = globalSettings.restorePreviewState and globalSettings.previewState self.actionPreviewChecked.append(liveMode) self.actionLivePreviewChecked.append(liveMode) metrics = QFontMetrics(self.editBoxes[-1].font()) self.editBoxes[-1].setTabStopWidth(globalSettings.tabWidth * metrics.width(' ')) self.editBoxes[-1].textChanged.connect(self.updateLivePreviewBox) self.editBoxes[-1].undoAvailable.connect(self.actionUndo.setEnabled) self.editBoxes[-1].redoAvailable.connect(self.actionRedo.setEnabled) self.editBoxes[-1].copyAvailable.connect(self.enableCopy) self.editBoxes[-1].document().modificationChanged.connect(self.modificationChanged) if globalSettings.useFakeVim: self.installFakeVimHandler(self.editBoxes[-1]) return self.getSplitter(-1)
def addPort(self, name, isOutput = False, flags = 0, ptr = None): port = QNEPort(self) port.setName(name) port.setIsOutput(isOutput) port.setNEBlock(self) port.setPortFlags(flags) port.setPtr(ptr) fontmetrics = QFontMetrics(self.scene().font()); width = fontmetrics.width(name) height = fontmetrics.height() if width > self.width - self.horzMargin: self.width = width + self.horzMargin self.height += height path = QPainterPath() path.addRoundedRect(-self.width/2, -self.height/2, self.width, self.height, 5, 5) self.setPath(path) y = -self.height / 2 + self.vertMargin + port.radius() for port_ in self.childItems(): if port_.type() != QNEPort.Type: continue if port_.isOutput(): port_.setPos(self.width/2 + port.radius(), y) else: port_.setPos(-self.width/2 - port.radius(), y) y += height; return port
def draw_frequency_marker(self, x_pos, frequency): if frequency is None: self.clear_frequency_marker() return y1 = self.sceneRect().y() y2 = self.sceneRect().y() + self.sceneRect().height() if self.frequency_marker is None: pen = QPen(constants.LINECOLOR, 0) self.frequency_marker = [None, None] self.frequency_marker[0] = self.addLine(x_pos, y1, x_pos, y2, pen) self.frequency_marker[1] = self.addSimpleText("") self.frequency_marker[1].setBrush(QBrush(constants.LINECOLOR)) font = QFont() font.setBold(True) font.setPointSize(int(font.pointSize() * 1.25)+1) self.frequency_marker[1].setFont(font) self.frequency_marker[0].setLine(x_pos, y1, x_pos, y2) scale_x, scale_y = self.__calc_x_y_scale(self.sceneRect()) self.frequency_marker[1].setTransform(QTransform.fromScale(scale_x, scale_y), False) self.frequency_marker[1].setText("Tune to " + Formatter.big_value_with_suffix(frequency, decimals=3)) font_metric = QFontMetrics(self.frequency_marker[1].font()) text_width = font_metric.width("Tune to") * scale_x text_width += (font_metric.width(" ") * scale_x) / 2 self.frequency_marker[1].setPos(x_pos-text_width, 0.95*y1)
def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(WebDatabasesDialog, self).__init__(parent) self.setupUi(self) self.removeButton.clicked.connect(self.databasesTree.removeSelected) self.removeAllButton.clicked.connect(self.databasesTree.removeAll) model = WebDatabasesModel(self) self.__proxyModel = E5TreeSortFilterProxyModel(self) self.__proxyModel.setFilterKeyColumn(-1) self.__proxyModel.setSourceModel(model) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.databasesTree.setModel(self.__proxyModel) fm = QFontMetrics(self.font()) header = fm.width("m") * 30 self.databasesTree.header().resizeSection(0, header) self.databasesTree.model().sort( self.databasesTree.header().sortIndicatorSection(), Qt.AscendingOrder) self.databasesTree.expandAll()
def paintEvent(self, ev) -> None: if self._text is not None: painter = QPainter(self) font = painter.font() fm = QFontMetrics(font) width = fm.width(self._text) painter.drawText(self.width() // 2 - width // 2, 14, self._text) painter.end()
def labelResize(self, label, event, text): """ Change label's text due to its size. """ width = self.taskArea.width() - 320 # if get width from event: width = event.size().width() # resizing will stop when full text is shown in label metrics = QFontMetrics(label.font()) ellipsis = metrics.elidedText(text, Qt.ElideRight, width) label.setText(ellipsis)
def __init__(self, *args, **kwargs): if "windowtype" in kwargs: self.windowname = kwargs["windowtype"] del kwargs["windowtype"] else: self.windowname = "XML Object" super().__init__(*args, **kwargs) self.resize(900, 500) self.setMinimumSize(QSize(300, 300)) self.centralwidget = QWidget(self) self.setWidget(self.centralwidget) self.entity = None font = QFont() font.setFamily("Consolas") font.setStyleHint(QFont.Monospace) font.setFixedPitch(True) font.setPointSize(10) self.dummywidget = QWidget(self) self.dummywidget.setMaximumSize(0,0) self.verticalLayout = QVBoxLayout(self.centralwidget) self.verticalLayout.addWidget(self.dummywidget) self.goto_id_action = ActionWithOwner("Go To ID", self, action_owner=self) self.addAction(self.goto_id_action) self.goto_shortcut = QKeySequence(Qt.CTRL+Qt.Key_G) self.goto_id_action.setShortcut(self.goto_shortcut) #self.goto_id_action.setShortcutContext(Qt.WidgetShortcut) self.goto_id_action.setAutoRepeat(False) self.goto_id_action.triggered_owner.connect(self.open_new_window) self.textbox_xml = XMLTextEdit(self.centralwidget) self.button_xml_savetext = QPushButton(self.centralwidget) self.button_xml_savetext.setText("Save XML") self.button_xml_savetext.setMaximumWidth(400) self.textbox_xml.setLineWrapMode(QTextEdit.NoWrap) self.textbox_xml.setContextMenuPolicy(Qt.CustomContextMenu) self.textbox_xml.customContextMenuRequested.connect(self.my_context_menu) metrics = QFontMetrics(font) self.textbox_xml.setTabStopWidth(4 * metrics.width(' ')) self.textbox_xml.setFont(font) self.verticalLayout.addWidget(self.textbox_xml) self.verticalLayout.addWidget(self.button_xml_savetext) self.setWindowTitle(self.windowname)
def sizeHint(self, option, qidx): fm = QFontMetrics(option.font) x = self.xmargin y = 0 for sz, tag in self._positions(option, qidx): x += sz.width() + self.xmargin + 2 * self.xpadding y = self.ymargin * 2 + fm.height() return QSize(x, y)
def setFont(self, f): # recalculate all of our metrics/offsets fm = QFontMetrics(f) self.font_width = fm.width('X') self.font_height = fm.height() self.updateScrollbars() # TODO: assert that we are using a fixed font & find out if we care? QAbstractScrollArea.setFont(self, f) return
def __init__(self, parent): super().__init__(parent) font = self.font() font.setPointSize(16) met = QFontMetrics(font) scoreLineHeight = met.height() self.setFont(font) self.setMinimumHeight(scoreLineHeight) self.setMinimumWidth(met.width('30'))
def __init__(self, parent=None): super(EditorBase, self).__init__(parent) # linuxcnc defaults self.idle_line_reset = False # don't allow editing by default self.setReadOnly(True) # Set the default font self.font = QFont() self.font.setFamily('Courier') self.font.setFixedPitch(True) self.font.setPointSize(12) self.setFont(self.font) self.setMarginsFont(self.font) # Margin 0 is used for line numbers fontmetrics = QFontMetrics(self.font) self.setMarginsFont(self.font) self.setMarginWidth(0, fontmetrics.width("00000") + 6) self.setMarginLineNumbers(0, True) self.setMarginsBackgroundColor(QColor("#cccccc")) # Clickable margin 1 for showing markers self.setMarginSensitivity(1, False) # setting marker margin width to zero make the marker highlight line self.setMarginWidth(1, 0) #self.matginClicked.connect(self.on_margin_clicked) self.markerDefine(QsciScintilla.RightArrow, self.ARROW_MARKER_NUM) self.setMarkerBackgroundColor(QColor("#ffe4e4"), self.ARROW_MARKER_NUM) # Brace matching: enable for a brace immediately before or after # the current position # self.setBraceMatching(QsciScintilla.SloppyBraceMatch) # Current line visible with special background color self.setCaretLineVisible(True) self.setCaretLineBackgroundColor(QColor("#ffe4e4")) # Set custom gcode lexer self.set_gcode_lexer() # Don't want to see the horizontal scrollbar at all # Use raw message to Scintilla here (all messages are documented # here: http://www.scintilla.org/ScintillaDoc.html) #self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0) self.SendScintilla(QsciScintilla.SCI_SETSCROLLWIDTH,700) self.SendScintilla(QsciScintilla.SCI_SETSCROLLWIDTHTRACKING) # default gray background self.set_background_color('#C0C0C0') # not too small self.setMinimumSize(200, 100) self.filepath = None
def setButtonSize(self): """ Set the size of the changeOrder button """ font = self.pushButton_changeOrder.font() fontMetrics = QFontMetrics(font) width = fontMetrics.width(self.pushButton_changeOrder.text()) + 25 self.pushButton_changeOrder.setMinimumWidth(width) self.pushButton_changeOrder.setMaximumWidth(width) self.pushButton_changeOrder.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
def adjustSpacing(self): """Adjust line spacing & indent size based on font & indent factor. """ self.lineSpacing = QFontMetrics(self.mainFont, self.printer).lineSpacing() self.indentSize = self.indentFactor * self.lineSpacing
class CustomDelegate(QStyledItemDelegate): "A custom delegate for the model/view framework" POPUP = pyqtSignal() CONTEXT_ON = False # Gallery states G_NORMAL, G_DOWNLOAD = range(2) def __init__(self, parent=None): super().__init__() QPixmapCache.setCacheLimit(app_constants.THUMBNAIL_CACHE_SIZE[0]* app_constants.THUMBNAIL_CACHE_SIZE[1]) self._painted_indexes = {} #misc.FileIcon.refresh_default_icon() self.file_icons = misc.FileIcon() if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() self.font_size = app_constants.GALLERY_FONT[1] self.font_name = app_constants.GALLERY_FONT[0] if not self.font_name: self.font_name = QWidget().font().family() self.title_font = QFont() self.title_font.setBold(True) self.title_font.setFamily(self.font_name) self.artist_font = QFont() self.artist_font.setFamily(self.font_name) if self.font_size is not 0: self.title_font.setPixelSize(self.font_size) self.artist_font.setPixelSize(self.font_size) self.title_font_m = QFontMetrics(self.title_font) self.artist_font_m = QFontMetrics(self.artist_font) t_h = self.title_font_m.height() a_h = self.artist_font_m.height() self.text_label_h = a_h + t_h * 2 self.W = app_constants.THUMB_W_SIZE self.H = app_constants.THUMB_H_SIZE + app_constants.GRIDBOX_LBL_H#self.text_label_h #+ app_constants.GRIDBOX_LBL_H def key(self, key): "Assigns an unique key to indexes" if key in self._painted_indexes: return self._painted_indexes[key] else: k = hash(key) self._painted_indexes[key] = str(k) return str(k) def paint(self, painter, option, index): assert isinstance(painter, QPainter) if index.data(Qt.UserRole+1): if app_constants.HIGH_QUALITY_THUMBS: painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.Antialiasing) gallery = index.data(Qt.UserRole+1) title = gallery.title artist = gallery.artist title_color = app_constants.GRID_VIEW_TITLE_COLOR artist_color = app_constants.GRID_VIEW_ARTIST_COLOR label_color = app_constants.GRID_VIEW_LABEL_COLOR # Enable this to see the defining box #painter.drawRect(option.rect) # define font size if 20 > len(title) > 15: title_size = "font-size:{}px;".format(self.font_size) elif 30 > len(title) > 20: title_size = "font-size:{}px;".format(self.font_size-1) elif 40 > len(title) >= 30: title_size = "font-size:{}px;".format(self.font_size-2) elif 50 > len(title) >= 40: title_size = "font-size:{}px;".format(self.font_size-3) elif len(title) >= 50: title_size = "font-size:{}px;".format(self.font_size-4) else: title_size = "font-size:{}px;".format(self.font_size) if 30 > len(artist) > 20: artist_size = "font-size:{}px;".format(self.font_size) elif 40 > len(artist) >= 30: artist_size = "font-size:{}px;".format(self.font_size-1) elif len(artist) >= 40: artist_size = "font-size:{}px;".format(self.font_size-2) else: artist_size = "font-size:{}px;".format(self.font_size) #painter.setPen(QPen(Qt.NoPen)) #option.rect = option.rect.adjusted(11, 10, 0, 0) option.rect.setWidth(self.W) option.rect.setHeight(self.H) rec = option.rect.getRect() x = rec[0] y = rec[1] w = rec[2] h = rec[3] text_area = QTextDocument() text_area.setDefaultFont(option.font) text_area.setHtml(""" <head> <style> #area {{ display:flex; width:140px; height:10px }} #title {{ position:absolute; color: {4}; font-weight:bold; {0} }} #artist {{ position:absolute; color: {5}; top:20px; right:0; {1} }} </style> </head> <body> <div id="area"> <center> <div id="title">{2} </div> <div id="artist">{3} </div> </div> </center> </body> """.format(title_size, artist_size, title, artist, title_color, artist_color)) text_area.setTextWidth(w) #chapter_area = QTextDocument() #chapter_area.setDefaultFont(option.font) #chapter_area.setHtml(""" #<font color="black">{}</font> #""".format("chapter")) #chapter_area.setTextWidth(w) def center_img(width): new_x = x if width < w: diff = w - width offset = diff//2 new_x += offset return new_x # if we can't find a cached image pix_cache = QPixmapCache.find(self.key(gallery.profile)) if isinstance(pix_cache, QPixmap): self.image = pix_cache img_x = center_img(self.image.width()) if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) else: self.image = QPixmap(gallery.profile) img_x = center_img(self.image.width()) QPixmapCache.insert(self.key(gallery.profile), self.image) if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) # draw star if it's favorited if gallery.fav == 1: painter.drawPixmap(QPointF(x,y), QPixmap(app_constants.STAR_PATH)) if app_constants._REFRESH_EXTERNAL_VIEWER: if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() if gallery.state == self.G_DOWNLOAD: painter.save() dl_box = QRect(x, y, w, 20) painter.setBrush(QBrush(QColor(0,0,0,123))) painter.setPen(QColor('white')) painter.drawRect(dl_box) painter.drawText(dl_box, Qt.AlignCenter, 'Downloading...') painter.restore() else: if app_constants.DISPLAY_GALLERY_TYPE: self.type_icon = self.file_icons.get_file_icon(gallery.path) if self.type_icon and not self.type_icon.isNull(): self.type_icon.paint(painter, QRect(x+2, y+app_constants.THUMB_H_SIZE-16, 16, 16)) if app_constants.USE_EXTERNAL_PROG_ICO: if self.external_icon and not self.external_icon.isNull(): self.external_icon.paint(painter, QRect(x+w-30, y+app_constants.THUMB_H_SIZE-28, 28, 28)) def draw_text_label(lbl_h): #draw the label for text painter.save() painter.translate(x, y+app_constants.THUMB_H_SIZE) box_color = QBrush(QColor(label_color))#QColor(0,0,0,123)) painter.setBrush(box_color) rect = QRect(0, 0, w, lbl_h) #x, y, width, height painter.fillRect(rect, box_color) painter.restore() return rect if option.state & QStyle.State_MouseOver or\ option.state & QStyle.State_Selected: title_layout = self.text_layout(title, w, self.title_font, self.title_font_m) artist_layout = self.text_layout(artist, w, self.artist_font, self.artist_font_m) t_h = title_layout.boundingRect().height() a_h = artist_layout.boundingRect().height() if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(min(t_h+a_h+3, app_constants.GRIDBOX_LBL_H)) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) clipping = QRectF(x, y+app_constants.THUMB_H_SIZE, w, app_constants.GRIDBOX_LBL_H - 10) title_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE), clip=clipping) artist_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE+t_h), clip=clipping) #painter.fillRect(option.rect, QColor) else: if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(self.text_label_h) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) # draw text painter.save() alignment = QTextOption(Qt.AlignCenter) alignment.setUseDesignMetrics(True) title_rect = QRectF(0,0,w, self.title_font_m.height()) artist_rect = QRectF(0,self.artist_font_m.height(),w, self.artist_font_m.height()) painter.translate(x, y+app_constants.THUMB_H_SIZE) if app_constants.GALLERY_FONT_ELIDE: painter.setFont(self.title_font) painter.setPen(QColor(title_color)) painter.drawText(title_rect, self.title_font_m.elidedText(title, Qt.ElideRight, w-10), alignment) painter.setPen(QColor(artist_color)) painter.setFont(self.artist_font) alignment.setWrapMode(QTextOption.NoWrap) painter.drawText(artist_rect, self.title_font_m.elidedText(artist, Qt.ElideRight, w-10), alignment) else: text_area.setDefaultFont(QFont(self.font_name)) text_area.drawContents(painter) ##painter.resetTransform() painter.restore() if option.state & QStyle.State_Selected: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(164,164,164,120))) p_path = QPainterPath() p_path.setFillRule(Qt.WindingFill) p_path.addRoundedRect(selected_rect, 5,5) p_path.addRect(x,y, 20, 20) p_path.addRect(x+w-20,y, 20, 20) painter.drawPath(p_path.simplified()) #painter.fillRect(selected_rect, QColor(164,164,164,120)) painter.restore() #if option.state & QStyle.State_Selected: # painter.setPen(QPen(option.palette.highlightedText().color())) else: super().paint(painter, option, index) def text_layout(self, text, width, font, font_metrics): "Lays out wrapped text" text_option = QTextOption(Qt.AlignCenter) text_option.setUseDesignMetrics(True) text_option.setWrapMode(QTextOption.WordWrap) layout = QTextLayout(text, font) layout.setTextOption(text_option) leading = font_metrics.leading() height = 0 layout.setCacheEnabled(True) layout.beginLayout() while True: line = layout.createLine() if not line.isValid(): break line.setLineWidth(width) height += leading line.setPosition(QPointF(0, height)) height += line.height() layout.endLayout() return layout def sizeHint(self, StyleOptionViewItem, QModelIndex): return QSize(self.W, self.H)
def paintEvent(self, event): if self.model is None: return fm = QFontMetrics(self.font()) timestampWidth = fm.width("9999-99-99 99:99 ") size = fm.height() indicatorSize = int(size * 0.8) offset = int(1.5 * (size - indicatorSize)) minY = event.rect().y() maxY = minY + event.rect().height() + size minY -= size painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.TextAntialiasing) y = 0 for row in range(self.model.rowCount()): x = 0 if minY <= y <= maxY: painter.save() painter.setPen(self.palette().color(QPalette.Text)) if row == self.selectedRow: painter.fillRect(x, y + (offset * 0.8), self.width(), size, self.palette().highlight()) painter.setPen(self.palette().color( QPalette.HighlightedText)) #timestamp = self.model.data( #self.model.index(row, TIMESTAMP)).toDateTime() timestamp = self.model.data(self.model.index(row, TIMESTAMP)) painter.drawText(x, y + size, timestamp.toString(TIMESTAMPFORMAT)) #print(timestamp.toString(TIMESTAMPFORMAT)) x += timestampWidth temperature = self.model.data( self.model.index(row, TEMPERATURE)) #temperature = temperature.toDouble()[0] temperature = float(temperature) if temperature < 20: color = QColor(0, 0, int(255 * (20 - temperature) / 20)) elif temperature > 25: color = QColor(int(255 * temperature / 100), 0, 0) else: color = QColor(0, int(255 * temperature / 100), 0) painter.setPen(Qt.NoPen) painter.setBrush(color) painter.drawEllipse(x, y + offset, indicatorSize, indicatorSize) x += size rawPh = self.model.data(self.model.index(row, RAWPH)) #rawPh = rawPh.toDouble()[0] rawPh = float(rawPh) if rawPh < 7: color = QColor(int(255 * rawPh / 10), 0, 0) elif rawPh >= 8: color = QColor(0, 0, int(255 * rawPh / 10)) else: color = QColor(0, int(255 * rawPh / 10), 0) painter.setBrush(color) painter.drawEllipse(x, y + offset, indicatorSize, indicatorSize) x += size flocPh = self.model.data(self.model.index(row, FLOCCULATEDPH)) #flocPh = flocPh.toDouble()[0] flocPh = float(flocPh) if flocPh < 7: color = QColor(int(255 * flocPh / 10), 0, 0) elif flocPh >= 8: color = QColor(0, 0, int(255 * flocPh / 10)) else: color = QColor(0, int(255 * flocPh / 10), 0) painter.setBrush(color) painter.drawEllipse(x, y + offset, indicatorSize, indicatorSize) painter.restore() painter.save() x += size flow = self.model.data(self.model.index(row, INLETFLOW)) #flow = flow.toDouble()[0] flow = float(flow) char = None if flow <= 0: char = WaterQualityView.FLOWCHARS[0] elif flow < 3.6: char = WaterQualityView.FLOWCHARS[1] elif flow > 4.7: char = WaterQualityView.FLOWCHARS[2] if char is not None: painter.setFont(self.flowfont) painter.drawText(x, y + size, char) painter.restore() y += size if y > maxY: break
def setFont(self): self.waterfont, ok = QFontDialog.getFont() # 显示字体对话框 if ok: # 判断是否选择了字体 self.lineEdit.setFont(self.waterfont) # 设置水印文字的字体 self.fontSize = QFontMetrics(self.waterfont) # 获取字体尺寸 self.fontInfo = QFontInfo(self.waterfont) # 获取字体信息
def paintGL(self): if self.STATUS == PresentationStatus.STARTING_UP: print("skipping paintgl") return glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) if self.STATUS == PresentationStatus.TARGET_SHOW: # SHOW TARGET msgs = self.MESSAGE.split('\n') font = QFont('Arial', 50) font.setBold(True) fm = QFontMetrics(font) if self.TARGET_INDEX >= 0: print( colored("Target index is %s." % self.TARGET_INDEX, 'cyan')) #im = self.images[self.imageOrder[int(self.TARGET_INDEX)]] side = min(self.width(), self.height() * 0.5) preserve_aspect = True col_count = self.width() / (self.cols * 2) row_count = self.height() / (self.rows * 2) col_w = self.width() / self.cols row_h = self.height() / self.rows i = 0 #print(colored("Length of image list: %s" % len(self.imageOrder), 'cyan')) for (index, turned) in self.fields: im = self.images[ self.imageOrder[index]] if turned else self.images[ self.backside] col = i % self.cols row = math.floor(float(i) / float(self.cols)) x_center = col_count + (col_w * col) y_center = row_count + (row_h * row) side = min(col_w, row_h) * 0.8 if preserve_aspect: im_path = '' for k in self.images.keys(): if self.images[k] == im: im_path = k break im_dim = self.image_values[im_path] if im_dim.width() > im_dim.height(): w = side h = int( float(side) * (float(im_dim.height()) / float(im_dim.width()))) else: h = side w = int( float(side) * (float(im_dim.width()) / float(im_dim.height()))) else: w = side h = w self.display_image(im, x_center - (w / 2), y_center - (h / 2), w, h, i == self.TARGET_INDEX) i += 1 y = self.height() * 0.8 v_align = Qt.AlignTop else: y = self.height() / 2 if len(msgs) > 0: y -= (len(msgs) - 1) * fm.boundingRect( msgs[0]).height() * 0.5 v_align = Qt.AlignVCenter # WRITE TEXT for msg in msgs: fontw = fm.boundingRect(msg).width() self.render_text(self.width() / 2, y, msg, font, Qt.white, Qt.AlignHCenter, v_align) y += fm.boundingRect(msg).height() + 5 if self.STATUS == PresentationStatus.SUB_TRIAL_IN_PROGRESS: # SUB-TRIAL self.display_sub_trial() if self.STATUS == PresentationStatus.STARTING_UP: # INIT WINDOW font = QFont("Arial", min(self.width(), self.height()) * 0.05) font.setBold(True) fm = QFontMetrics(font) text = "Starting..." fontw = fm.boundingRect(text).width() fonth = fm.boundingRect(text).height() self.render_text(self.width() / 2, self.height() / 2, text, font, Qt.white, Qt.AlignHCenter, Qt.AlignVCenter)
def standardIconSize() -> QSize: size = QFontMetrics(QFont()).height() * 6 return QSize(size, size)
class GridScene(ZoomableScene): def __init__(self, parent=None): self.draw_grid = False self.font_metrics = QFontMetrics(QFont()) self.center_freq = 433.92e6 self.frequencies = [] self.frequency_marker = None super().__init__(parent) self.setSceneRect(0, 0, 10, 10) def drawBackground(self, painter: QPainter, rect: QRectF): if self.draw_grid and len(self.frequencies) > 0: painter.setPen(QPen(painter.pen().color(), 0)) parent_width = self.parent().width() if hasattr( self.parent(), "width") else 750 view_rect = self.parent().view_rect() if hasattr( self.parent(), "view_rect") else rect font_width = self.font_metrics.width( Formatter.big_value_with_suffix(self.center_freq) + " ") x_grid_size = int(view_rect.width() / parent_width * font_width) # x_grid_size = int(0.1 * view_rect.width()) if 0.1 * view_rect.width() > 1 else 1 y_grid_size = 1 x_mid = np.where(self.frequencies == 0)[0] x_mid = int(x_mid[0]) if len(x_mid) > 0 else 0 left = int(rect.left()) - (int(rect.left()) % x_grid_size) left = left if left > 0 else 0 top = rect.top() - (rect.top() % y_grid_size) bottom = rect.bottom() - (rect.bottom() % y_grid_size) right_border = int( rect.right()) if rect.right() < len(self.frequencies) else len( self.frequencies) scale_x, scale_y = util.calc_x_y_scale(rect, self.parent()) fh = self.font_metrics.height() x_range = list(range(x_mid, left, -x_grid_size)) + list( range(x_mid, right_border, x_grid_size)) lines = [QLineF(x, rect.top(), x, bottom-fh*scale_y) for x in x_range] \ + [QLineF(rect.left(), y, rect.right(), y) for y in np.arange(top, bottom, y_grid_size)] pen = painter.pen() pen.setStyle(Qt.DotLine) painter.setPen(pen) painter.drawLines(lines) painter.scale(scale_x, scale_y) counter = -1 # Counter for Label for every second line for x in x_range: freq = self.frequencies[x] counter += 1 if freq == 0: counter = 0 if freq != 0 and (counter % 2 != 0): # Label for every second line continue value = Formatter.big_value_with_suffix( self.center_freq + freq, 2) font_width = self.font_metrics.width(value) painter.drawText( QPointF(x / scale_x - font_width / 2, bottom / scale_y), value) def draw_frequency_marker(self, x_pos, frequency): if frequency is None: self.clear_frequency_marker() return y1 = self.sceneRect().y() y2 = self.sceneRect().y() + self.sceneRect().height() if self.frequency_marker is None: pen = QPen(settings.LINECOLOR, 0) self.frequency_marker = [None, None] self.frequency_marker[0] = self.addLine(x_pos, y1, x_pos, y2, pen) self.frequency_marker[1] = self.addSimpleText("") self.frequency_marker[1].setBrush(QBrush(settings.LINECOLOR)) font = QFont() font.setBold(True) font.setPointSize(int(font.pointSize() * 1.25) + 1) self.frequency_marker[1].setFont(font) self.frequency_marker[0].setLine(x_pos, y1, x_pos, y2) scale_x, scale_y = util.calc_x_y_scale(self.sceneRect(), self.parent()) self.frequency_marker[1].setTransform( QTransform.fromScale(scale_x, scale_y), False) self.frequency_marker[1].setText( "Tune to " + Formatter.big_value_with_suffix(frequency, decimals=3)) font_metric = QFontMetrics(self.frequency_marker[1].font()) text_width = font_metric.width("Tune to") * scale_x text_width += (font_metric.width(" ") * scale_x) / 2 self.frequency_marker[1].setPos(x_pos - text_width, 0.95 * y1) def clear_frequency_marker(self): if self.frequency_marker is not None: self.removeItem(self.frequency_marker[0]) self.removeItem(self.frequency_marker[1]) self.frequency_marker = None def get_freq_for_pos(self, x: int) -> float: try: f = self.frequencies[x] except IndexError: return None return self.center_freq + f def clear(self): self.clear_frequency_marker() super().clear()
def minimumSizeHint(self): fm = QFontMetrics(self.font()) return QSize(fm.width("WWWW"), self.minimumHeight())
def __init__(self, parent=None): super(RDFXmlEditor, self).__init__(parent) self.parent = parent self.indicatorDefine(QsciScintilla.PlainIndicator, self.INDICATOR_URL) self.setCaretLineVisible(True) self.setEolMode(QsciScintilla.EolWindows) self.setEolVisibility(False) # Set the default font font = QFont() font.setFamily('Courier New') font.setFixedPitch(True) font.setPointSize(10) font.setBold(True) self.setFont(font) self.setMarginsFont(font) # Margin 0 is used for line numbers fontmetrics = QFontMetrics(font) self.setMarginsFont(font) self.setMarginWidth(0, fontmetrics.width("00000") + 6) self.setMarginLineNumbers(0, True) self.setMarginsBackgroundColor(QColor("#cccccc")) # Clickable margin 1 for showing markers self.setMarginSensitivity(1, True) self.marginClicked.connect(self.reactOnMarginClicked) self.markerDefine(QsciScintilla.RightArrow, self.ARROW_MARKER_NUM) self.setMarkerBackgroundColor(QColor("#ee1111"), self.ARROW_MARKER_NUM) self.setMarginSensitivity(2, True) self.setMarginType(2, QsciScintilla.SymbolMargin ) self.setFolding(QsciScintilla.CircledTreeFoldStyle,2) # Brace matching: enable for a brace immediately before or after # the current position # self.setBraceMatching(QsciScintilla.SloppyBraceMatch) self.setIndentationGuides(True) # Current line visible with special background color self.setWrapMode(QsciScintilla.WrapWhitespace) self.setCaretLineBackgroundColor(QColor("#ffe4e4")) self.lexer = QsciLexerXML() self.lexer.setDefaultFont(font) self.lexer.setColor(QColor(26, 26, 255, 250), QsciLexerXML.Tag) font = self.lexer.font(QsciLexerXML.Tag) font.setBold(True) self.lexer.setFont(font, QsciLexerXML.Tag) self.lexer.setColor(QColor(230, 115, 0, 250), QsciLexerXML.Attribute) font = self.lexer.font(QsciLexerXML.Attribute) font.setBold(True) self.lexer.setFont(font, QsciLexerXML.Attribute) self.lexer.setColor(QColor(0, 148, 43, 250), QsciLexerXML.HTMLDoubleQuotedString) font = self.lexer.font(QsciLexerXML.HTMLDoubleQuotedString) font.setBold(True) self.lexer.setFont(font, QsciLexerXML.HTMLDoubleQuotedString) #lexer.setColor(QColor(0, 153, 51, 250), QsciLexerXML.XMLStart) #lexer.setColor(QColor(0, 153, 51, 250), QsciLexerXML.XMLEnd) self.setLexer(self.lexer) #self.SendScintilla(QsciScintilla.SCI_STYLESETFONT, 1, 'Courier') # Don't want to see the horizontal scrollbar at all # Use raw message to Scintilla here (all messages are documented # here: http://www.scintilla.org/ScintillaDoc.html) self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0) # not too small self.setMinimumSize(600, 450) self.prevFind = [] self.firstFindDone = False
cellHeaderBaseColor = QColor(230, 230, 230) cellHeaderLineColor = QColor(220, 220, 220) cellHeaderHighlightLineColor = QColor(240, 240, 240) cellSelectionColor = QColor.fromRgbF(.2, .3, .7, .15) GlyphCellBufferHeight = .2 GlyphCellHeaderHeight = 14 headerFont = QFont() headerFont.setFamily('Lucida Sans Unicode') headerFont.insertSubstitution('Lucida Sans Unicode', 'Lucida Grande') headerFont.insertSubstitution('Lucida Sans Unicode', 'Luxi Sans') headerFont.setPointSize(platformSpecific.headerPointSize) voidFont = QFont(headerFont) voidFont.setPointSize(24) metrics = QFontMetrics(headerFont) arrowKeys = (Qt.Key_Up, Qt.Key_Down, Qt.Key_Left, Qt.Key_Right) class GlyphCollectionWidget(QWidget): """ A widget that presents a list of glyphs in cells. """ def __init__(self, parent=None): super(GlyphCollectionWidget, self).__init__(parent) self.setAttribute(Qt.WA_KeyCompression) self._glyphs = [] self._squareSize = 56 self._columns = 10 self._selection = set()
def __init__(self, parent=None): super().__init__(parent) self.filename = None self.fileBrowser = None self.mainWindow = parent self.debugging = False c = Configuration() self.pointSize = int(c.getFontSize()) self.tabWidth = int(c.getTab()) # Scrollbars self.verticalScrollBar().setStyleSheet("""border: 20px solid black; background-color: darkgreen; alternate-background-color: #FFFFFF;""") self.horizontalScrollBar().setStyleSheet("""border: 20px solid black; background-color: darkgreen; alternate-background-color: #FFFFFF;""") # matched / unmatched brace color ... self.setMatchedBraceBackgroundColor(QColor('#000000')) self.setMatchedBraceForegroundColor(QColor('cyan')) self.setUnmatchedBraceBackgroundColor(QColor('#000000')) self.setUnmatchedBraceForegroundColor(QColor('red')) self.setBraceMatching(QsciScintilla.SloppyBraceMatch) # edge mode ... line at 79 characters self.setEdgeColumn(79) self.setEdgeMode(1) self.setEdgeColor(QColor('dark green')) # Set the default font self.font = QFont() system = platform.system().lower() if system == 'windows': self.font.setFamily('Consolas') else: self.font.setFamily('Monospace') self.font.setFixedPitch(True) self.font.setPointSize(self.pointSize) self.setFont(self.font) self.setMarginsFont(self.font) # Margin 0 is used for line numbers fontmetrics = QFontMetrics(self.font) self.setMarginsFont(self.font) self.setMarginWidth(0, fontmetrics.width("00000") + 5) self.setMarginLineNumbers(0, True) self.setMarginsBackgroundColor(QColor("#000000")) self.setMarginsForegroundColor(QColor("#FFFFFF")) # Margin 1 for breakpoints self.setMarginSensitivity(1, True) self.markerDefine(QsciScintilla.RightArrow, 8) self.setMarkerBackgroundColor(QColor('#FF0000'), 8) # variable for breakpoint self.breakpoint = False self.breakpointLine = None # FoldingBox self.setFoldMarginColors(QColor('dark green'), QColor('dark green')) # CallTipBox self.setCallTipsForegroundColor(QColor('#FFFFFF')) self.setCallTipsBackgroundColor(QColor('#282828')) self.setCallTipsHighlightColor(QColor('#3b5784')) self.setCallTipsStyle(QsciScintilla.CallTipsContext) self.setCallTipsPosition(QsciScintilla.CallTipsBelowText) self.setCallTipsVisible(-1) # change caret's color self.SendScintilla(QsciScintilla.SCI_SETCARETFORE, QColor('#98fb98')) self.setCaretWidth(4) # tab Width self.setIndentationsUseTabs(False) self.setTabWidth(self.tabWidth) # use Whitespaces instead tabs self.SendScintilla(QsciScintilla.SCI_SETUSETABS, False) self.setAutoIndent(True) self.setTabIndents(True) # BackTab self.setBackspaceUnindents(True) # Current line visible with special background color or not :) #self.setCaretLineVisible(False) #self.setCaretLineVisible(True) #self.setCaretLineBackgroundColor(QColor("#020202")) self.setMinimumSize(300, 300) # get style self.style = None # Call the Color-Function: ... self.setPythonStyle() #self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0) # Contextmenu self.setContextMenuPolicy(Qt.ActionsContextMenu) undoAction = QAction("Undo", self) undoAction.triggered.connect(self.undoContext) redoAction = QAction("Redo", self) redoAction.triggered.connect(self.redoContext) sepAction1 = QAction("", self) sepAction1.setSeparator(True) cutAction = QAction("Cut", self) cutAction.triggered.connect(self.cutContext) copyAction = QAction("Copy", self) copyAction.triggered.connect(self.copyContext) pasteAction = QAction("Paste", self) pasteAction.triggered.connect(self.pasteContext) sepAction2 = QAction("", self) sepAction2.setSeparator(True) sepAction3 = QAction("", self) sepAction3.setSeparator(True) selectAllAction = QAction("Select All", self) selectAllAction.triggered.connect(self.getContext) sepAction4 = QAction("", self) sepAction4.setSeparator(True) breakpointAction = QAction("Run until Breakpoint", self) breakpointAction.triggered.connect(self.breakpointContext) terminalAction = QAction("Open Terminal", self) terminalAction.triggered.connect(self.termContext) self.addAction(undoAction) self.addAction(redoAction) self.addAction(sepAction1) self.addAction(cutAction) self.addAction(copyAction) self.addAction(pasteAction) self.addAction(sepAction2) self.addAction(selectAllAction) self.addAction(sepAction3) self.addAction(breakpointAction) self.addAction(sepAction4) self.addAction(terminalAction) # signals self.SCN_FOCUSIN.connect(self.onFocusIn) self.textChanged.connect(self.onTextChanged) self.marginClicked.connect(self.onMarginClicked)
def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(640, 480) self.vindu = QtWidgets.QWidget(MainWindow) self.vindu.setStyleSheet(_fromUtf8('notusedasyet')) #MainWindow.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) self.filename = "" self.vindu.setObjectName(_fromUtf8("vindu")) self.verticalLayout = PyQt5.QtWidgets.QVBoxLayout(self.vindu) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/ico/python.png")), QtGui.QIcon.Normal, QtGui.QIcon.On) MainWindow.setWindowIcon(icon) self.verticalLayout.setContentsMargins(0,0,0,0) self.verticalLayout.setSpacing(0) self.verticalLayout.setObjectName(_fromUtf8('verticalLayout')) self.codebox = Qsci.QsciScintilla(self.vindu) self.codebox.setToolTip(_fromUtf8("")) self.codebox.setWhatsThis(_fromUtf8("")) self.codebox.setAutoFillBackground(False) self.codebox.setFrameShape(QtWidgets.QFrame.NoFrame) self.codebox.setObjectName(_fromUtf8("codebox")) self.verticalLayout.addWidget(self.codebox) MainWindow.setCentralWidget(self.vindu) #toolbar self.toolBar = QtWidgets.QToolBar(MainWindow) self.toolBar.setAutoFillBackground(False) self.toolBar.setIconSize(QtCore.QSize(32, 32)) self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.toolBar.setObjectName(_fromUtf8("toolBar2")) MainWindow.addToolBar(QtCore.Qt.LeftToolBarArea, self.toolBar) self.toolBar.addSeparator() #toolbar2 debugger #self.toolBar2 = QtGui.QToolBar(MainWindow) #self.toolBar2.setAutoFillBackground(False) #self.toolBar2.setIconSize(QtCore.QSize(32, 32)) #self.toolBar2.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) #self.toolBar2.setObjectName(_fromUtf8("toolBar")) # MainWindow.addToolBar(QtCore.Qt.RightToolBarArea, self.toolBar2) # self.toolBar2.addSeparator() #getting ready for debugger self.codebox.setMarginSensitivity(1, True) self.codebox.marginClicked.connect(self.on_margin_clicked) self.codebox.markerDefine(QsciScintilla.FullRectangle, self.ARROW_MARKER_NUM) self.codebox.setMarkerBackgroundColor(QColor("#ee1111"), self.ARROW_MARKER_NUM) #first action Newfile self.toolBar.newAction = QtWidgets.QAction(QtGui.QIcon(":/ico/new.png"),"New",self.toolBar) self.toolBar.newAction.setStatusTip("Clear TextBox or make new document.") self.toolBar.newAction.setShortcut("Ctrl+N") self.toolBar.newAction.triggered.connect(self.newfile) #second Action OpenFile self.toolBar.secondAction = QtWidgets.QAction(QtGui.QIcon(":/ico/open.png"),"Open",self.toolBar) self.toolBar.secondAction.setStatusTip("Create a new document from scratch.") self.toolBar.secondAction.setShortcut("Ctrl+O") self.toolBar.secondAction.triggered.connect(self.open) # action 3 save file self.toolBar.Action3 = QtWidgets.QAction(QtGui.QIcon(":/ico/save.png"),"Save",self.toolBar) self.toolBar.Action3.setStatusTip("Save Your File.") self.toolBar.Action3.setShortcut("Ctrl+S") self.toolBar.Action3.triggered.connect(self.savefile) #action 4 run file self.toolBar.Action4 = QtWidgets.QAction(QtGui.QIcon(":/ico/run32.png"),"Run",self.toolBar) self.toolBar.Action4.setStatusTip("Run") self.toolBar.Action4.setShortcut("Ctrl+E") self.toolBar.Action4.triggered.connect(self.runto) #action 21 debug #self.toolBar2.Action21 = QtGui.QAction(QtGui.QIcon(":/ico/run32.png"),"Debug",self.toolBar) #self.toolBar2.Action21.setStatusTip("Debug File.") #self.toolBar2.Action21.setShortcut("Ctrl+7") #self.toolBar2.Action21.triggered.connect(self.debugto) #action 6 undo self.toolBar.Action6 = QtWidgets.QAction(QtGui.QIcon(":/ico/undo.png"),"Redo",self.toolBar) self.toolBar.Action6.setStatusTip("Undo.") self.toolBar.Action6.setShortcut("Ctrl+Z") self.toolBar.Action6.triggered.connect(self.codebox.undo) #action 7 redo self.toolBar.Action7 = QtWidgets.QAction(QtGui.QIcon(":/ico/redo.png"),"Redo",self.toolBar) self.toolBar.Action7.setStatusTip("Redo.") self.toolBar.Action7.setShortcut("Ctrl+Y") self.toolBar.Action7.triggered.connect(self.codebox.redo) #action8 rerset Folding self.toolBar.Action8 = QtWidgets.QAction(QtGui.QIcon(":/ico/align-justify.png"),"Reset Folding",self.toolBar) self.toolBar.Action8.setStatusTip("Reset Folding.") self.toolBar.Action8.setShortcut("Ctrl+R") self.toolBar.Action8.triggered.connect(self.nofoldingl) #actions9 CircledTreeFoldStyle self.toolBar.Action9 = QtWidgets.QAction(QtGui.QIcon(":/ico/bullet.png"),"Circled Tree Folding",self.toolBar) self.toolBar.Action9.setStatusTip("Circled Tree Folding.") self.toolBar.Action9.setShortcut("Ctrl+C") self.toolBar.Action9.triggered.connect(self.Circledfold) #actions10 plainFoldStyle self.toolBar.Action10 = QtWidgets.QAction(QtGui.QIcon(":/ico/number.png"),"Plain Folding",self.toolBar) self.toolBar.Action10.setStatusTip("Plain Folding") self.toolBar.Action10.setShortcut("Ctrl+P") self.toolBar.Action10.triggered.connect(self.plainfold) # fonts self.toolBar.Action21 = QtWidgets.QAction(QtGui.QIcon(":/ico4/font.png"), "Fonts", self.toolBar) self.toolBar.Action21.setStatusTip("Fonts") self.toolBar.Action21.setShortcut("Ctrl+F") self.toolBar.Action21.triggered.connect(self.font_choice) #web baby self.toolBar.Action11 = QtWidgets.QAction(QtGui.QIcon(":/ico/web.png"),"Hex-rays Homepage",self.toolBar) self.toolBar.Action11.setStatusTip("Home of Hex-rays") self.toolBar.Action11.setShortcut("Ctrl+W") self.toolBar.Action11.triggered.connect(self.webopen) #irc self.toolBar.Action12 = QtWidgets.QAction(QtGui.QIcon(":/ico3/settings.png"),"Open Ida Pro Python SDK",self.toolBar) self.toolBar.Action12.setStatusTip("Ida Pro Python SDK") self.toolBar.Action12.setShortcut("Ctrl+I") self.toolBar.Action12.triggered.connect(self.sdkopen) #github Python self.toolBar.Action14 = QtWidgets.QAction(QtGui.QIcon(":/ico/github.png"),"Open git python",self.toolBar) self.toolBar.Action14.setStatusTip("Open git python") self.toolBar.Action14.setShortcut("Ctrl+G") self.toolBar.Action14.triggered.connect(self.gitopen) #auther me :) self.toolBar.Action15 = QtWidgets.QAction(QtGui.QIcon(":/ico/auth.png"),"Author",self.toolBar) self.toolBar.Action15.setStatusTip("Author") self.toolBar.Action15.setShortcut("Ctrl+B") self.toolBar.Action15.triggered.connect(self.Author) #toggle off code regonision self.toolBar.Action16 = QtWidgets.QAction(QtGui.QIcon(":/ico2/pythonminus.png"),"Disable Code recognition",self.toolBar) self.toolBar.Action16.setStatusTip("Disable Code recognition") self.toolBar.Action16.setShortcut("Alt+D") self.toolBar.Action16.triggered.connect(self.Diablecode) #toogle on self.toolBar.Action17 = QtWidgets.QAction(QtGui.QIcon(":/ico2/pypluss.png"),"Enable Code recognition",self.toolBar) self.toolBar.Action17.setStatusTip("Enable Code recognition") self.toolBar.Action17.setShortcut("Alt+E") self.toolBar.Action17.triggered.connect(self.Reiablecode) # zoom in self.toolBar.Action18 = QtWidgets.QAction(QtGui.QIcon(":/ico3/in.png"),"Zoom In",self.toolBar) self.toolBar.Action18.setStatusTip("Zoom In") self.toolBar.Action18.setShortcut("CTRL+SHIFT++") self.toolBar.Action18.triggered.connect(self.udder) #zoom out self.toolBar.Action19 = QtWidgets.QAction(QtGui.QIcon(":/ico3/out.png"),"Zoom Out",self.toolBar) self.toolBar.Action19.setStatusTip("Zoom Out") self.toolBar.Action19.setShortcut("CTRL+SHIFT+-") self.toolBar.Action19.triggered.connect(self.odder) self.toolBar.Action20 = QtWidgets.QAction(QtGui.QIcon(":/ico3/10.png"),"Profile Code",self.toolBar) self.toolBar.Action20.setStatusTip("Profile Code") self.toolBar.Action20.setShortcut("CTRL+SHIFT+E") self.toolBar.Action20.triggered.connect(self.runtoprob) #actions self.toolBar.addAction(self.toolBar.newAction) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.secondAction) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action3) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action4) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action6) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action7) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action8) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action9) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action10) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action21) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action11) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action12) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action14) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action15) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action16) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action17) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action18) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action19) self.toolBar.addSeparator() self.toolBar.addAction(self.toolBar.Action20) #self.toolBar2.addAction(self.toolBar.Action21) #self.toolBar2.addSeparator() #font self.skrift = QFont() self.skrift.setFamily('Consolas') self.skrift.setFixedPitch(True) self.skrift.setPointSize(12) self.codebox.setFont(self.skrift) #python style self.lexer = QsciLexerPython(self.codebox) self.lexer.setFont(self.skrift) self.lexer.setEolFill(True) #api test not working api = Qsci.QsciAPIs(self.lexer) API_FILE = dn+'\\Python.api' API_FILE2 = dn+'\\idc.api' API_FILE3 = dn+'\\idaapi.api' api.load(API_FILE) api.load(API_FILE2) api.load(API_FILE3) api.prepare() self.codebox.setAutoCompletionThreshold(0) self.codebox.setAutoCompletionThreshold(6) self.codebox.setAutoCompletionThreshold(8) self.codebox.setAutoCompletionSource(Qsci.QsciScintilla.AcsAPIs) self.lexer.setDefaultFont(self.skrift) self.codebox.setLexer(self.lexer) self.codebox.SendScintilla(QsciScintilla.SCI_STYLESETFONT, 1, 'Consolas') #line numbers fontmetrics = QFontMetrics(self.skrift) self.codebox.setMarginsFont(self.skrift) self.codebox.setMarginWidth(0, fontmetrics.width("00000") + 6) self.codebox.setTabWidth(4) #brace self.codebox.setBraceMatching(QsciScintilla.SloppyBraceMatch) #auto line tab =4 self.codebox.setAutoIndent(True) #scroolbar self.codebox.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 1) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow)
class Ui_MarkWindow(QMainWindow): # 构造方法 def __init__(self): super(Ui_MarkWindow, self).__init__() self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint) # 只显示关闭按钮 self.setupUi(self) # 初始化窗体设置 # 自动生成的代码,用来对窗体进行设置 def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(578, 418) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") # 设置图片显示列表 self.listWidget = QtWidgets.QListWidget(self.centralwidget) self.listWidget.setGeometry(QtCore.QRect(0, 0, 141, 391)) self.listWidget.setObjectName("listWidget") # 设置加载图片按钮 self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(150, 0, 75, 23)) self.pushButton.setObjectName("pushButton") self.groupBox = QtWidgets.QGroupBox(self.centralwidget) self.groupBox.setGeometry(QtCore.QRect(150, 30, 421, 151)) self.groupBox.setObjectName("groupBox") # 设置文字水印单选按钮 self.radioButton = QtWidgets.QRadioButton(self.groupBox) self.radioButton.setGeometry(QtCore.QRect(20, 20, 101, 16)) self.radioButton.setChecked(True) # 默认选中 self.radioButton.setObjectName("radioButton") self.label = QtWidgets.QLabel(self.groupBox) self.label.setGeometry(QtCore.QRect(30, 50, 54, 16)) self.label.setObjectName("label") # 设置要输入水印文字的文本框 self.lineEdit = QtWidgets.QLineEdit(self.groupBox) self.lineEdit.setGeometry(QtCore.QRect(90, 50, 241, 20)) self.lineEdit.setObjectName("lineEdit") # 设置“字体设置”按钮 self.pushButton_2 = QtWidgets.QPushButton(self.groupBox) self.pushButton_2.setGeometry(QtCore.QRect(340, 50, 75, 23)) self.pushButton_2.setObjectName("pushButton_2") # 设置图片水印单选按钮 self.radioButton_2 = QtWidgets.QRadioButton(self.groupBox) self.radioButton_2.setGeometry(QtCore.QRect(20, 80, 91, 16)) self.radioButton_2.setChecked(False) # 默认不选中 self.radioButton_2.setObjectName("radioButton_2") # 设置选择水印图片按钮 self.pushButton_3 = QtWidgets.QPushButton(self.groupBox) self.pushButton_3.setGeometry(QtCore.QRect(340, 110, 75, 23)) self.pushButton_3.setObjectName("pushButton_3") self.label_2 = QtWidgets.QLabel(self.groupBox) self.label_2.setGeometry(QtCore.QRect(30, 110, 54, 16)) self.label_2.setObjectName("label_2") # 设置显示水印图片路径的文本框 self.lineEdit_2 = QtWidgets.QLineEdit(self.groupBox) self.lineEdit_2.setGeometry(QtCore.QRect(90, 110, 241, 20)) self.lineEdit_2.setObjectName("lineEdit_2") self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget) self.groupBox_2.setGeometry(QtCore.QRect(150, 190, 421, 71)) self.groupBox_2.setObjectName("groupBox_2") self.label_3 = QtWidgets.QLabel(self.groupBox_2) self.label_3.setGeometry(QtCore.QRect(270, 31, 54, 21)) self.label_3.setObjectName("label_3") # 设置水印位置选择框 self.comboBox = QtWidgets.QComboBox(self.groupBox_2) self.comboBox.setGeometry(QtCore.QRect(330, 30, 71, 22)) self.comboBox.setObjectName("comboBox") self.comboBox.addItem('左上角') self.comboBox.addItem('右上角') self.comboBox.addItem('左下角') self.comboBox.addItem('右下角') self.comboBox.addItem('居中位置') self.comboBox.setCurrentIndex(0) # 设置默认选择第一项 self.label_4 = QtWidgets.QLabel(self.groupBox_2) self.label_4.setGeometry(QtCore.QRect(20, 30, 51, 21)) self.label_4.setObjectName("label_4") # 设置水印透明度的滑动条 self.horizontalSlider = QtWidgets.QSlider(self.groupBox_2) self.horizontalSlider.setGeometry(QtCore.QRect(70, 30, 181, 22)) self.horizontalSlider.setMinimum(1) self.horizontalSlider.setMaximum(10) self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider.setObjectName("horizontalSlider") self.groupBox_3 = QtWidgets.QGroupBox(self.centralwidget) self.groupBox_3.setGeometry(QtCore.QRect(150, 270, 421, 71)) self.groupBox_3.setObjectName("groupBox_3") self.label_6 = QtWidgets.QLabel(self.groupBox_3) self.label_6.setGeometry(QtCore.QRect(20, 30, 61, 21)) self.label_6.setObjectName("label_6") # 设置显示保存路径的文本框 self.lineEdit_3 = QtWidgets.QLineEdit(self.groupBox_3) self.lineEdit_3.setGeometry(QtCore.QRect(80, 30, 241, 20)) self.lineEdit_3.setObjectName("lineEdit_3") # 设置选择图片保存路径的按钮 self.pushButton_4 = QtWidgets.QPushButton(self.groupBox_3) self.pushButton_4.setGeometry(QtCore.QRect(330, 30, 75, 23)) self.pushButton_4.setObjectName("pushButton_4") #设置执行按钮 self.pushButton_5 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_5.setGeometry(QtCore.QRect(480, 350, 75, 23)) self.pushButton_5.setObjectName("pushButton_5") MainWindow.setCentralWidget(self.centralwidget) #设置状态栏 self.statusBar = QtWidgets.QStatusBar(MainWindow) self.statusBar.setObjectName("statusBar") self.statusBar.showMessage('准备就绪…… ') # 设置状态栏默认值 MainWindow.setStatusBar(self.statusBar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) # 自动生成的代码,用来设置窗体中控件的默认值 def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "图片批量添加水印")) self.pushButton.setText(_translate("MainWindow", "加载图片")) self.groupBox.setTitle(_translate("MainWindow", "水印设置")) self.radioButton.setText(_translate("MainWindow", "添加文字水印")) self.label.setText(_translate("MainWindow", "水印文字:")) self.pushButton_2.setText(_translate("MainWindow", "字体设置")) self.radioButton_2.setText(_translate("MainWindow", "添加图片水印")) self.pushButton_3.setText(_translate("MainWindow", "浏览")) self.label_2.setText(_translate("MainWindow", "水印图片:")) self.groupBox_2.setTitle(_translate("MainWindow", "透明度及位置设置")) self.label_3.setText(_translate("MainWindow", "水印位置:")) self.label_4.setText(_translate("MainWindow", "透明度:")) self.groupBox_3.setTitle(_translate("MainWindow", "路径设置")) self.label_6.setText(_translate("MainWindow", "保存位置:")) self.pushButton_4.setText(_translate("MainWindow", "浏览")) self.pushButton_5.setText(_translate("MainWindow", "执行")) # 关联“加载图片”按钮的方法 self.pushButton.clicked.connect(self.getFiles) # 关联“字体设置”按钮的方法 self.pushButton_2.clicked.connect(self.setFont) # 关联“选择图片”按钮的方法 self.pushButton_3.clicked.connect(self.setImg) # 关联“选择保存路径”按钮的方法 self.pushButton_4.clicked.connect(self.msg) # 关联“执行”按钮的方法 self.pushButton_5.clicked.connect(self.addMark) # 关联列表单击方法,用来预览选中的图片 self.listWidget.itemClicked.connect(self.itemClick) # 设置字体 def setFont(self): self.waterfont, ok = QFontDialog.getFont() # 显示字体对话框 if ok: # 判断是否选择了字体 self.lineEdit.setFont(self.waterfont) # 设置水印文字的字体 self.fontSize = QFontMetrics(self.waterfont) # 获取字体尺寸 self.fontInfo = QFontInfo(self.waterfont) # 获取字体信息 # 是否为图片 def isImg(self, file): file = file.lower() if file == '.jpg': return True elif file == '.png': return True elif file == '.jpeg': return True elif file == '.bmp': return True else: return False # 获取所有文件 def getFiles(self): try: # 选择图片文件夹路径 self.img_path = QFileDialog.getExistingDirectory( None, "选择图片文件夹路径", os.getcwd()) self.list = os.listdir(self.img_path) # 遍历选择的文件夹 num = 0 # 记录图片数量 self.listWidget.clear() # 清空列表项 for i in range(0, len(self.list)): # 遍历图片列表 filepath = os.path.join(self.img_path, self.list[i]) # 记录遍历到的文件名 if os.path.isfile(filepath): # 判断是否为文件 imgType = os.path.splitext(filepath)[1] # 获取扩展名 if self.isImg(imgType): # 判断是否为图片 num += 1 # 数量加1 self.item = QtWidgets.QListWidgetItem( self.listWidget) # 创建列表项 self.item.setText(self.list[i]) # 显示图片列表 self.statusBar.showMessage('共有图片 ' + str(num) + ' 张') # 显示图片总数 except Exception: QMessageBox.warning(None, '警告', '请选择一个有效路径……', QMessageBox.Ok) # 预览图片 def itemClick(self, item): os.startfile(self.img_path + '\\' + item.text()) # 选择水印图片 def setImg(self): try: # waterimg即为选择的水印图片,第二形参为对话框标题,第三个为对话框打开后默认的路径 self.waterimg = QFileDialog.getOpenFileName( None, '选择水印图片', 'C:\\', "图片文件(*.jpeg;*.png;*.jpg;*.bmp)") self.lineEdit_2.setText(self.waterimg[0]) # 显示选择的水印图片 except Exception as e: print(e) # 选择保存路径 def msg(self): try: # dir_path即为选择的文件夹的绝对路径,第二形参为对话框标题,第三个为对话框打开后默认的路径 self.dir_path = QFileDialog.getExistingDirectory( None, "选择路径", os.getcwd()) self.lineEdit_3.setText(self.dir_path) # 显示选择的保存路径 except Exception as e: print(e) # 文字水印 def textMark(self, img, newImgPath): try: im = Image.open(img).convert('RGBA') # 打开原始图片,并转换为RGBA newImg = Image.new('RGBA', im.size, (255, 255, 255, 0)) # 存储添加水印后的图片 # 创建字体,说明:默认使用楷体,如果需要使用其他字体,需要将字体文件复制到当前目录中 # 然后对下面第一个参数进行修改,可以使用self.fontInfo.family()动态获取字体名称,后面加扩展名即可 font = ImageFont.truetype('simkai.ttf', self.fontInfo.pointSize()) imagedraw = ImageDraw.Draw(newImg) # 创建绘制对象 imgwidth, imgheight = im.size # 记录图片大小 txtwidth = self.fontSize.maxWidth() * len( self.lineEdit.text()) # 获取字体宽度 txtheight = self.fontSize.height() # 获取字体高度 # 设置水印文字位置 if self.comboBox.currentText() == '左上角': position = (0, 0) elif self.comboBox.currentText() == '左下角': position = (0, imgheight - txtheight) elif self.comboBox.currentText() == '右上角': position = (imgwidth - txtwidth, 0) elif self.comboBox.currentText() == '右下角': position = (imgwidth - txtwidth, imgheight - txtheight) elif self.comboBox.currentText() == '居中位置': position = (imgwidth / 2, imgheight / 2) # 设置文本颜色 imagedraw.text(position, self.lineEdit.text(), font=font, fill="#FCA454") # 设置透明度 alpha = newImg.split()[3] alpha = ImageEnhance.Brightness(alpha).enhance( int(self.horizontalSlider.value()) / 10.0) newImg.putalpha(alpha) Image.alpha_composite(im, newImg).save(newImgPath) # 保存图片 except Exception: QMessageBox.warning(None, '错误', '图片格式有误,请重新选择……', QMessageBox.Ok) # 图片水印 def imgMark(self, img, newImgPath): im = Image.open(img) # 打开原始图片 mark = Image.open(self.lineEdit_2.text()) # 打开水印图片 rgbaim = im.convert('RGBA') # 将原始图片转换为RGBA rgbamark = mark.convert('RGBA') # 将水印图片转换为RGBA imgwidth, imgheight = rgbaim.size # 获取原始图片尺寸 nimgwidth, nimgheight = rgbamark.size # 获取水印图片尺寸 # 缩放水印图片 scale = 10 markscale = max(imgwidth / (scale * nimgwidth), imgheight / (scale * nimgheight)) newsize = (int(nimgwidth * markscale), int(nimgheight * markscale) ) # 计算新的尺寸大小 rgbamark = rgbamark.resize(newsize, resample=Image.ANTIALIAS) # 重新设置水印图片大小 nimgwidth, nimgheight = rgbamark.size # 获取水印图片缩放后的尺寸 # 计算水印位置 if self.comboBox.currentText() == '左上角': position = (0, 0) elif self.comboBox.currentText() == '左下角': position = (0, imgheight - nimgheight) elif self.comboBox.currentText() == '右上角': position = (imgwidth - nimgwidth, 0) elif self.comboBox.currentText() == '右下角': position = (imgwidth - nimgwidth, imgheight - nimgheight) elif self.comboBox.currentText() == '居中位置': position = (int(imgwidth / 2), int(imgheight / 2)) # 设置透明度:img.point(function)接受一个参数,且对图片中的每一个点执行这个函数,这个函数是一个匿名函数,使用lambda表达式来完成 # convert()函数,用于不同模式图像之间的转换,模式“L”为灰色图像,它的每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。 # 在PIL中,从模式“RGB”转换为“L”模式是按照下面的公式转换的:L = R * 299/1000 + G * 587/1000+ B * 114/1000 rgbamarkpha = rgbamark.convert("L").point( lambda x: x / int(self.horizontalSlider.value())) rgbamark.putalpha(rgbamarkpha) # 水印位置 rgbaim.paste(rgbamark, position, rgbamarkpha) try: rgbaim.save(newImgPath) # 保存水印图片 except Exception: QMessageBox.warning(None, '错误', '请选择其他路径……', QMessageBox.Ok) # 添加水印 def addMark(self): if self.lineEdit_3.text() == '': # 判断是否选择了保存路径 QMessageBox.warning(None, '警告', '请选择保存路径', QMessageBox.Ok) return else: num = 0 # 记录处理图片数量 for i in range(0, self.listWidget.count()): # 遍历图片列表 # 设置原始图片路径(包括文件名) filepath = os.path.join(self.img_path, self.listWidget.item(i).text()) # 设置水印图片保存路径(包括文件名) newfilepath = os.path.join(self.lineEdit_3.text(), self.listWidget.item(i).text()) if self.radioButton.isChecked(): # 判断是否选择文字水印单选按钮 if self.lineEdit.text() == '': # 判断是否输入了水印文字 QMessageBox.warning(None, '警告', '请输入水印文字', QMessageBox.Ok) return else: self.textMark(filepath, newfilepath) # 调用textMark方法添加文字水印 num += 1 # 处理图片数量加1 else: if self.lineEdit_2.text() != '': # 判断水印图片不为空 self.imgMark(filepath, newfilepath) # 调用imgMark方法添加图片水印 num += 1 # 处理图片数量加1 else: QMessageBox.warning(None, '警告', '请选择水印图片', QMessageBox.Ok) self.statusBar.showMessage('任务完成,此次共处理 ' + str(num) + ' 张图片') # 显示处理图片总数
class Dot(LayoutEngine): """ The dot graphviz engine """ def __init__(self, graph, show_subgraphs=True): self.graph = graph self.default_node_width = 100 self.default_node_height = 100 self.default_min_nodes_dist = self.default_node_height self.font = QFont("Arial", 12) self.fm = QFontMetrics(self.font) self.margins = 20 self.show_subgraphs = show_subgraphs self.graph.depth_x_pos = [0] def process(self, n, graph, index=0, nb_brothers=0, depth=0, stage=0): n.processed += 1 width = 0 height = 0 if ("pos" in n.kwargs): n.pos[0] = n.kwargs["pos"][0] n.pos[1] = n.kwargs["pos"][1] n.size[0] = n.kwargs["size"][0] n.size[1] = n.kwargs["size"][1] if len(graph.depth_x_pos) > depth: graph.depth_x_pos[ depth] += n.size[0] + self.default_min_nodes_dist else: graph.depth_x_pos.append(n.size[0] + self.default_min_nodes_dist) for i, oe in enumerate(n.out_edges): if (oe.dest.processed < 20): self.process(oe.dest, graph, i, len(n.out_edges), depth=depth + 1) return if ("label" in n.kwargs.keys()): if (n.kwargs["label"] != ""): rect = self.fm.boundingRect(n.kwargs["label"]) width = rect.width() + self.margins height = rect.height() + self.margins if width == 0 or height == 0: width = self.default_node_width height = self.default_node_height if (type(n) == Graph and self.show_subgraphs): n.depth_x_pos = [0] for nn in n.nodes: self.process(nn, n, 0, len(n.nodes), depth=depth) _, _, w_, h_ = n.getRect() #w_+=2*self.default_min_nodes_dist width = w_ if w_ > width else width height = h_ if h_ > height else height width += 2 * self.margins height += 2 * self.margins n.size[0] = width n.size[1] = height if len(n.in_edges) == 0: n.pos[0] = graph.depth_x_pos[depth] + self.margins + width / 2 n.pos[1] = self.default_node_height / 2 + self.margins + height / 2 if len(graph.depth_x_pos) > depth: graph.depth_x_pos[ depth] += width / 2 + self.default_min_nodes_dist else: graph.depth_x_pos.append(width / 2 + self.default_min_nodes_dist) else: x = (width / 2 + self.default_min_nodes_dist) * ( -(nb_brothers - 1) / 2 + index) y = 0 for i, oe in enumerate(n.out_edges): if (oe.dest.processed < 20): self.process(oe.dest, graph, i, len(n.out_edges), depth=depth + 1) for edg in n.in_edges: if (edg.source.processed == 0): self.process(edg.source, graph) if (n.parent_graph == edg.source.parent_graph): x += edg.source.pos[0] if (y < edg.source.pos[1] + height / 2 + self.default_min_nodes_dist): y = edg.source.pos[ 1] + height / 2 + self.default_min_nodes_dist x /= len(n.in_edges) n.pos[0] = x n.pos[1] = y for i, oe in enumerate(n.out_edges): if oe.dest.processed < 20: self.process(oe.dest, graph, i, len(n.out_edges)) if (type(n) == Graph and self.show_subgraphs): n.depth_x_pos = [0] for nn in n.nodes: self.process(nn, n, 0, len(n.nodes), depth=depth) def build_graph(self, graph): for n in graph.nodes: n.processed = 0 for i, n in enumerate(graph.nodes): if (n.processed < 3): self.process(n, graph) """ for n in graph.nodes: if(n.pos[0]<n.size[0]/2): for node in graph.nodes: node.pos[0]+=(n.size[0]/2)-n.pos[0] """ _, _, graph.size[0], graph.size[1] = graph.getRect() graph.pos[0] = graph.size[0] / 2 graph.pos[1] = graph.size[1] / 2 def build(self): self.graph.depth_x_pos = [0] self.build_graph(self.graph)
"""Summary """ from PyQt5.QtCore import QPointF, QRectF, Qt from PyQt5.QtGui import QFontMetrics, QPainterPath from PyQt5.QtWidgets import QGraphicsItem, QGraphicsPathItem, QGraphicsRectItem, QGraphicsSimpleTextItem from cadnano.views.pathview import pathstyles as styles from cadnano.gui.palette import getColorObj, getPenObj, getNoPen, getNoBrush, getSolidBrush _BASE_WIDTH = styles.PATH_BASE_WIDTH _toHelixNumFont = styles.XOVER_LABEL_FONT # precalculate the height of a number font. Assumes a fixed font # and that only numbers will be used for labels _FM = QFontMetrics(_toHelixNumFont) _ENAB_BRUSH = getSolidBrush() # Also for the helix number label _NO_BRUSH = getNoBrush() # _RECT = QRectF(0, 0, baseWidth, baseWidth) _X_SCALE = styles.PATH_XOVER_LINE_SCALE_X # control point x constant _Y_SCALE = styles.PATH_XOVER_LINE_SCALE_Y # control point y constant _RECT = QRectF(0, 0, _BASE_WIDTH, _BASE_WIDTH) class XoverNode3(QGraphicsRectItem): """ This is a QGraphicsRectItem to allow actions and also a QGraphicsSimpleTextItem to allow a label to be drawn Attributes: is_forward (TYPE): Description """ def __init__(self, virtual_helix_item, xover_item, strand3p, idx): """Summary
def update_font(self): metrics = QFontMetrics(self.font()) elided = metrics.elidedText(self.parent.video.title, Qt.ElideRight, self.width() * 1.8) self.setText(elided)
pen = QPen(color, penWidth) brush = QBrush(color) pen.setCapStyle(Qt.FlatCap) self.setPen(pen) self._low_cap.setBrush(brush) self._high_cap.setBrush(brush) # end def # end class _TO_HELIX_NUM_FONT = styles.XOVER_LABEL_FONT # precalculate the height of a number font. Assumes a fixed font # and that only numbers will be used for labels _FM = QFontMetrics(_TO_HELIX_NUM_FONT) _ENAB_BRUSH = QBrush(Qt.SolidPattern) # Also for the helix number label _NO_BRUSH = QBrush(Qt.NoBrush) # _rect = QRectF(0, 0, baseWidth, baseWidth) _xScale = styles.PATH_XOVER_LINE_SCALE_X # control point x constant _yScale = styles.PATH_XOVER_LINE_SCALE_Y # control point y constant _rect = QRectF(0, 0, _BASE_WIDTH, _BASE_WIDTH) _blankRect = QRectF(0, 0, 2 * _BASE_WIDTH, _BASE_WIDTH) PPL5 = QPainterPath() # Left 5' PainterPath PPR5 = QPainterPath() # Right 5' PainterPath PPL3 = QPainterPath() # Left 3' PainterPath PPR3 = QPainterPath() # Right 3' PainterPath # set up PPL5 (left 5' blue square)
def paint(self, painter: QtGui.QPainter, option: 'QStyleOptionViewItem', index: QtCore.QModelIndex) -> None: """ Paints the message on the screen :param painter: Controls actual painting :param option: Options for painting :param index: Index of item :return: """ if not index.isValid(): return painter.save( ) # Save current state, before altering for custom painting painter.setRenderHints(QPainter.Antialiasing) context = index.model().chat_message_contexts()[index.row()] message_text = index.data(Qt.DisplayRole) profile_pix: QPixmap = index.data(Qt.DecorationRole) # Determine message rect message_font = QApplication.font() message_fm = QFontMetrics(message_font) if context.is_sender: # Paint text with 10 pixel padding message_rect = message_fm.boundingRect( option.rect.left(), option.rect.top() + MessageItemDelegate.profile_padding / 2, option.rect.width() - MessageItemDelegate.total_pfp_width, 0, Qt.AlignRight | Qt.AlignTop | Qt.TextWordWrap, message_text) # Draw bubble rect bubble_rect = QRect( message_rect.left() - MessageItemDelegate.profile_padding / 2, message_rect.top() - MessageItemDelegate.profile_padding / 2, message_rect.width() + MessageItemDelegate.profile_padding, message_rect.height() + MessageItemDelegate.profile_padding) blue = QColor(35, 57, 93) painter.setBrush(blue) painter.setPen(blue) painter.drawRoundedRect(bubble_rect, 5, 5) painter.setPen(Qt.white) painter.setFont(message_font) painter.drawText(message_rect, Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, message_text) # Paint icon profile_rect = QRect( message_rect.right() + MessageItemDelegate.profile_padding, option.rect.top(), MessageItemDelegate.icon_radius, MessageItemDelegate.icon_radius) painter.drawPixmap(profile_rect, profile_pix) else: # Paint icon profile_rect = QRect(option.rect.left(), option.rect.top(), MessageItemDelegate.icon_radius, MessageItemDelegate.icon_radius) painter.drawPixmap(profile_rect, profile_pix) # Paint text with 10 pixel padding message_rect = message_fm.boundingRect( profile_rect.right() + MessageItemDelegate.profile_padding, option.rect.top() + MessageItemDelegate.profile_padding / 2, option.rect.width() - MessageItemDelegate.total_pfp_width, 0, Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, message_text) # Draw bubble rect bubble_rect = QRect( message_rect.left() - MessageItemDelegate.profile_padding / 2, message_rect.top() - MessageItemDelegate.profile_padding / 2, message_rect.width() + MessageItemDelegate.profile_padding, message_rect.height() + MessageItemDelegate.profile_padding) gray = QColor(105, 105, 105) painter.setBrush(gray) painter.setPen(gray) painter.drawRoundedRect(bubble_rect, 5, 5) painter.setPen(Qt.white) painter.setFont(message_font) painter.drawText(message_rect, Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, message_text) painter.restore() # Reset to state before changes
def sizeHint(self): fm = QFontMetrics(self.font()) size = fm.height() return QSize( fm.width("9999-99-99 99:99 ") + (size * 4), (size / 4) + (size * self.model.rowCount()))
class PlotWidget(QWidget): """ Lightweight plot widget base class Don't instantiate directly - use one of the base classes. """ def __init__(self, parent): QWidget.__init__(self, parent) # always draw background as black self.setBackgroundColor(Qt.black) self.setAutoFillBackground(True) # pen to draw the axes self.axesPen = QPen(Qt.gray) self.axesPen.setWidth(1) # font fontSize = self.getSettingsFontSize() self.setFontSize(fontSize) # xticks. Lists of PlotTicks self.xticks = None # yticks self.yticks = None # text labels list of PlotTexts self.labels = [] # fontmetrics self.fontMetrics = QFontMetrics(self.font()) def haveData(self): """ Returns True if data has been set """ raise NotImplmentedError('haveData() must be implemented') def getSettingsFontSize(self): "Get the default font size from settings" settings = QSettings() settings.beginGroup('Plot') fontSize = settings.value('FontSize', DEFAULT_FONT_SIZE, int) settings.endGroup() return fontSize def setFontSize(self, size): "Set the font point size" font = self.font() font.setPointSize(size) self.setFont(font) self.update() def setYRange(self, ymin=None, ymax=None): """ Set the Y range. Pass None for autoscale for either or both """ self.yrange = (ymin, ymax) self.update() def setXRange(self, xmin=None, xmax=None): """ Set the X range. Pass None for autoscale for either or both """ self.xrange = (xmin, xmax) self.update() def setXTicks(self, xticks=None): """ Pass a list of PlotTicks. None to reset. """ self.xticks = xticks self.update() def setYTicks(self, yticks=None): """ Pass a list of PlotTicks. None to reset. """ self.yticks = yticks self.update() def setBackgroundColor(self, color): "Sets the background color for the widget" palette = self.palette() palette.setColor(self.backgroundRole(), color) self.setPalette(palette) self.update() def addLabel(self, label): "Add a PlotLabel to be drawn" self.labels.append(label) self.update() def removeLabels(self): "remove all labels" self.labels = [] self.update() def getYDataRange(self): """ Get the range of the Y data to be plotted. """ return self.yrange def getXDataRange(self): """ Get the range of the X data to be plotted. """ return self.xrange @staticmethod def makeIntervals(start, end, nIntervals): """ Make a 'pretty' list of intervals. This was the hardest part. also returns number of decimals to display This is non-zero if floating point data """ interval = (end - start) / nIntervals ndecimals = 0 test = interval if interval >= 1: while test > 10: test /= 10 ndecimals += 1 else: while test < 10: test *= 10 ndecimals += 1 ndecimals = -ndecimals newinterval = numpy.ceil(test) * 10**ndecimals mininterval = int(start / newinterval) * newinterval tmp = mininterval intervals = [tmp] for n in range(nIntervals): tmp += newinterval intervals.append(tmp) if ndecimals < 0: npd = abs(ndecimals) else: npd = 0 return intervals, npd def drawText(self, paint, xloc, yloc, txt, flags): """ Helper method to draw text in given device coords For some reason Qt doesn't come with a method like this that moves the text around for given flags. """ # the position we are after is relative to the left bottom of the rect txtrect = self.fontMetrics.boundingRect(txt) if flags & Qt.AlignRight: xloc -= txtrect.width() if flags & Qt.AlignHCenter: xloc -= txtrect.width() / 2 if flags & Qt.AlignTop: yloc += txtrect.height() if flags & Qt.AlignVCenter: yloc += txtrect.height() / 2 if flags & Qt.TextDontClip: # remember: y is baseline txtrect.setRect(xloc, yloc - txtrect.height(), txtrect.width(), txtrect.height()) winrect = self.rect() if not winrect.contains(txtrect): return paint.drawText(xloc, yloc, txt) @staticmethod def formatInterval(interval, ndp): if ndp == 0: txt = "%d" % interval else: txt = "%.*f" % (ndp, interval) return txt def findLargestIntervalLabel(self, intervals, ndp): maxwidth = 0 for interval in intervals: txt = self.formatInterval(interval, ndp) textrect = self.fontMetrics.boundingRect(txt) txtwidth = textrect.width() if txtwidth > maxwidth: maxwidth = txtwidth return maxwidth def drawYTicks(self, paint, minYData, maxYData, yoffset, yscale, height): """ Draw the Y-ticks. Returns the size needed for the text """ paint.setPen(self.axesPen) flags = DEFAULT_YTICK_FLAGS if self.yticks is None: # create our own nIntervals = int(height / 20) intervals, ndp = self.makeIntervals(minYData, maxYData, nIntervals) # find width of largest interval and use that for width param txtwidth = self.findLargestIntervalLabel(intervals, ndp) for interval in intervals: if interval < minYData: continue txt = self.formatInterval(interval, ndp) yloc = (interval - minYData) * yscale + yoffset self.drawText(paint, txtwidth, yloc, txt, flags) # draw tick paint.drawLine(txtwidth, yloc, txtwidth + TICK_SIZE, yloc) else: # user supplied lastTick = self.xticks[-1] textrect = self.fontMetrics.boundingRect(lastTick.txt) txtwidth = textrect.width() for tick in self.xticks: yloc = (tick.loc - minYData) * yscale + yoffset if tick.pen is not None: oldPen = paint.pen() # save it paint.setPen(tick.pen) flags = DEFAULT_YTICK_FLAGS if tick.flags is not None: flags = tick.flags self.drawText(paint, txtwidth, yloc, tick.txt, flags) if tick.pen is not None: paint.setPen(oldPen) # restore # draw tick paint.drawLine(txtwidth, yloc, txtwidth + TICK_SIZE, yloc) return txtwidth + TICK_SIZE def drawXTicks(self, paint, minXData, maxXData, xoffset, xscale, width, height): """ Draw the X-ticks """ paint.setPen(self.axesPen) flags = DEFAULT_XTICK_FLAGS if self.xticks is None: # we have to create our own # do a guess and refine it until it fits txtwidth = 20 finished = False nIntervals = int(width / txtwidth) while not finished: intervals, ndp = self.makeIntervals(minXData, maxXData, nIntervals) txtwidth = self.findLargestIntervalLabel(intervals, ndp) nIntervals = int(width / txtwidth) # had to make it nIntervals+1 otherwise ended up # with infinite loop for long labels for some reason... finished = len(intervals) <= nIntervals + 1 for interval in intervals: if interval < minXData: continue txt = self.formatInterval(interval, ndp) xloc = (interval - minXData) * xscale + xoffset self.drawText(paint, xloc, height, txt, flags) # draw tick paint.drawLine(xloc, height, xloc, height + TICK_SIZE) else: # user supplied ticks for tick in self.xticks: xloc = (tick.loc - minXData) * xscale + xoffset if tick.pen is not None: oldPen = paint.pen() # save it paint.setPen(tick.pen) flags = DEFAULT_XTICK_FLAGS if tick.flags is not None: flags = tick.flags self.drawText(paint, xloc, height, tick.txt, flags) if tick.pen is not None: paint.setPen(oldPen) # restore # draw tick paint.drawLine(xloc, height, xloc, height + TICK_SIZE) def drawLabels(self, paint, minXData, minYData, xoffset, xscale, yoffset, yscale): """ Draw the user supplied labels onto the plot """ for label in self.labels: xloc = (label.xloc - minXData) * xscale + xoffset yloc = (label.yloc - minYData) * yscale + yoffset paint.setPen(label.pen) self.drawText(paint, xloc, yloc, label.txt, label.flags) def paintEvent(self, event): """ This is the main part - calculation and drawing happen here. In theory the calculation should happen separately on resize etc and paint should be simpler, but can't be bothered right now Delegates to paintData() in sublass to do actuall work """ paint = QPainter(self) # allow enough size under the x-axes for text and tick axes_ysize = self.fontMetrics.height() + TICK_SIZE size = self.size() plotheight = size.height() - axes_ysize yoffset = size.height() - axes_ysize axes_xsize = axes_ysize # in case there no data, we still have axes drawn ok # do we have data? if self.haveData(): minYData, maxYData = self.getYDataRange() minXData, maxXData = self.getXDataRange() xrange = (maxXData - minXData) yrange = (maxYData - minYData) # check we can draw lines # - might still be a problem if range set by user if xrange > 0 and yrange > 0: # NB: Qt works from top left, plots from bottom left yscale = -plotheight / yrange # axes labels axes_xsize = self.drawYTicks(paint, minYData, maxYData, yoffset, yscale, plotheight) # now we now the width of the axes_xsize calc the other parts plotwidth = size.width() - axes_xsize xoffset = axes_xsize xscale = plotwidth / xrange self.drawXTicks(paint, minXData, maxXData, xoffset, xscale, plotwidth, plotheight) # delegate to sublass self.paintData(paint, minXData, minYData, xoffset, xscale, yoffset, yscale) # labels self.drawLabels(paint, minXData, minYData, xoffset, xscale, yoffset, yscale) # axes paint.setPen(self.axesPen) paint.drawLine(axes_xsize, 0, axes_xsize, size.height() - axes_ysize) paint.drawLine(axes_xsize, size.height() - axes_ysize, size.width(), size.height() - axes_ysize) paint.end() def paintData(self, paint): """ To be implemented in sublass """ return NotImplementedError('must implement paintData') def sizeHint(self): """ This has to be implemented otherwise plot is very small! """ return QSize(400, 400)
def minimumSizeHint(self): size = self.sizeHint() fm = QFontMetrics(self.font()) size.setHeight(fm.height() * 3) return size
def setup_ui(self): """ Setup Ui """ main_wrap = QVBoxLayout() main_wrap.setContentsMargins(0, 0, 0, 0) # updatebar on top self.update_bar = UpdateBar(self) self.update_bar.onUpdateNowClicked.connect(self._update_dwarf) self.update_bar.setVisible(False) main_wrap.addWidget(self.update_bar) # main content h_box = QHBoxLayout() h_box.setContentsMargins(15, 15, 15, 15) wrapper = QVBoxLayout() head = QHBoxLayout() head.setContentsMargins(50, 10, 0, 10) # dwarf icon icon = QLabel() icon.setPixmap(QPixmap(utils.resource_path('assets/dwarf.svg'))) icon.setAlignment(Qt.AlignCenter) icon.setMinimumSize(QSize(125, 125)) icon.setMaximumSize(QSize(125, 125)) head.addWidget(icon) # main title v_box = QVBoxLayout() title = QLabel('Dwarf') title.setContentsMargins(0, 0, 0, 0) font = QFont('Anton', 100, QFont.Bold) font.setPixelSize(120) title.setFont(font) title.setMaximumHeight(125) title.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) title.setAlignment(Qt.AlignCenter) head.addWidget(title) sub_title_text = (self._pick_random_word(0) + ' ' + self._pick_random_word(1) + ' ' + self._pick_random_word(2) + ' ' + self._pick_random_word(3) + ' ' + self._pick_random_word(4)) sub_title_text = sub_title_text[:1].upper() + sub_title_text[1:] self._sub_title = QLabel(sub_title_text) font = QFont('OpenSans', 16, QFont.Bold) font.setPixelSize(24) self._sub_title.setFont(font) font_metric = QFontMetrics(self._sub_title.font()) self._char_width = font_metric.widthChar('#') self._sub_title.setAlignment(Qt.AlignCenter) self._sub_title.setContentsMargins(175, 0, 0, 20) self._sub_title.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) v_box.addLayout(head) v_box.addWidget(self._sub_title) wrapper.addLayout(v_box) recent = QLabel('Recent saved Sessions') font = recent.font() font.setPixelSize(14) font.setBold(True) # font.setPointSize(10) recent.setFont(font) wrapper.addWidget(recent) wrapper.addWidget(self._recent_list) h_box.addLayout(wrapper, stretch=False) buttonSpacer = QSpacerItem(15, 100, QSizePolicy.Fixed, QSizePolicy.Minimum) h_box.addItem(buttonSpacer) wrapper = QVBoxLayout() btn = QPushButton() ico = QIcon(QPixmap(utils.resource_path('assets/android.svg'))) btn.setIconSize(QSize(75, 75)) btn.setIcon(ico) btn.setToolTip('New Android Session') btn.clicked.connect(self._on_android_button) wrapper.addWidget(btn) btn = QPushButton() ico = QIcon(QPixmap(utils.resource_path('assets/apple.svg'))) btn.setIconSize(QSize(75, 75)) btn.setIcon(ico) btn.setToolTip('New iOS Session') btn.clicked.connect(self._on_ios_button) wrapper.addWidget(btn) btn = QPushButton() ico = QIcon(QPixmap(utils.resource_path('assets/local.svg'))) btn.setIconSize(QSize(75, 75)) btn.setIcon(ico) btn.setToolTip('New Local Session') btn.clicked.connect(self._on_local_button) wrapper.addWidget(btn) btn = QPushButton() ico = QIcon(QPixmap(utils.resource_path('assets/remote.svg'))) btn.setIconSize(QSize(75, 75)) btn.setIcon(ico) btn.setToolTip('New Remote Session') btn.clicked.connect(self._on_remote_button) wrapper.addWidget(btn) h_box.addLayout(wrapper, stretch=False) main_wrap.addLayout(h_box) self.setLayout(main_wrap)
def __init__(self, parent, filename, bp_add, bp_remove): super(Editor, self).__init__(None) self.par = parent self.filename = filename self.setReadOnly(True) self.bp_add = bp_add self.bp_remove = bp_remove self.bgcolor = '#535353' # FONT self.font = QFont() self.font.setFamily(FONT_FAMILY) self.font.setFixedPitch(True) self.font.setPointSize(10) self.font2 = QFont() self.font2.setFamily("Sans-Serif") self.font2.setFixedPitch(True) self.font2.setPointSize(10) self.setFont(self.font) self.setMarginsFont(self.font) self.setStyleSheet(""" QsciScintilla { font-size: 10px !important; } """) # DEFAULT BACKGROUND AND FOREGROUND self.setPaper(QColor(BACKGROUND_COLOR)) self.setColor(QColor(FOREGROUND_COLOR)) # MARGIN LINE NUMBERS fontmetrics = QFontMetrics(self.font) self.setMarginsFont(self.font2) self.setMarginWidth(0, fontmetrics.width("00000") + 4) self.setMarginLineNumbers(0, True) # MARGIN BACKGROUND AND FOREGROUND self.setMarginsBackgroundColor(QColor(MARGIN_BACKGROUND)) self.setMarginsForegroundColor(QColor(MARGIN_FOREGROUND)) # EDGE LINE # self.setEdgeMode(QsciScintilla.EdgeLine) # self.setEdgeColumn(150) # self.setEdgeColor(QColor(EDGE_COLOR)) # CURRENT LINE self.setCaretLineVisible(False) self.setCaretLineBackgroundColor(QColor("#8f8fc3")) self.setCaretForegroundColor(QColor("#0000ff")) # SELECTION BACKGROUND AND FOREGROUND self.setSelectionBackgroundColor(QColor(SEL_BACKGROUND)) self.setSelectionForegroundColor(QColor(SEL_FOREGROUND)) # TABS self.setIndentationsUseTabs(False) self.setIndentationWidth(4) self.setTabIndents(True) self.setAutoIndent(True) self.setBackspaceUnindents(True) self.setTabWidth(4) # TABS BACKGROUND AND FOREGROUND self.setIndentationGuidesBackgroundColor(QColor(IND_BACKGROUND)) self.setIndentationGuidesForegroundColor(QColor(IND_FOREGROUND)) # TABS BACKGROUND AND FOREGROUND self.setIndentationGuidesBackgroundColor(QColor(IND_BACKGROUND)) self.setIndentationGuidesForegroundColor(QColor(IND_FOREGROUND)) # FOLDING MARGIN self.setFolding(Qsci.QsciScintilla.PlainFoldStyle) self.setMarginWidth(2, 20) # (2,14) # FOLDING MARKERS self.markerDefine("V", Qsci.QsciScintilla.SC_MARKNUM_FOLDEROPEN) self.markerDefine(">", Qsci.QsciScintilla.SC_MARKNUM_FOLDER) self.markerDefine("V", Qsci.QsciScintilla.SC_MARKNUM_FOLDEROPENMID) self.markerDefine(">", Qsci.QsciScintilla.SC_MARKNUM_FOLDEREND) # FOLDING MARKERS BACKGROUND AND FOREGROUND self.setMarkerBackgroundColor(QColor(MARKER_BACKGROUND)) self.setMarkerForegroundColor(QColor(MARGIN_FOREGROUND)) self.setFoldMarginColors(QColor(FOLD_MARGIN_BACKGROUND), QColor(FOLD_MARGIN_BACKGROUND)) self.setMarginSensitivity(1, True) self.marginClicked.connect(self.on_margin_clicked) self.markerDefine(Qsci.QsciScintilla.SC_MARK_CIRCLE, self.BREAKPOINT_MARKER_NUM) self.setMarkerBackgroundColor(QColor("#ee1111"), self.BREAKPOINT_MARKER_NUM) self.markerDefine(Qsci.QsciScintilla.SC_MARK_BACKGROUND, self.BACKGROUND_BREAKPOINT_MARKER_NUM) self.setMarkerBackgroundColor(QColor("#ec6861"), self.BACKGROUND_BREAKPOINT_MARKER_NUM) self.markerDefine(Qsci.QsciScintilla.SC_MARK_BACKGROUND, self.BACKGROUND_MARKER_NUM) self.setMarkerBackgroundColor(QColor("#acec61"), self.BACKGROUND_MARKER_NUM) # FOLDING LINE DISABLE self.SendScintilla(Qsci.QsciScintilla.SCI_SETFOLDFLAGS, 0) # AUTO COMPLETION self.setAutoCompletionSource(Qsci.QsciScintilla.AcsDocument) self.setAutoCompletionThreshold(2) # DISABLE HORIZONTAL SCROLLBAR self.SendScintilla(Qsci.QsciScintilla.SCI_SETHSCROLLBAR, 0) self.setStyleSheet(""" QsciScintilla { border: 0px solid black; padding: 0px; border-radius: 0px; opacity: 100; font-size: 10px !important; } """) self.highlighted_lines = [] self.breakpoints = set()
def appPrefsChanged(self, prefs): font = self.view.font() font.setPointSize(prefs.tableFontSize) self.view.setFont(font) fm = QFontMetrics(font) self.view.verticalHeader().setDefaultSectionSize(fm.height() + 2)
def __init__(self, x: float, y: float, scene: QGraphicsScene, model_node: ModelNode, title: str = None, parent: QGraphicsItem = None, node_types: NodeTypes = None): """ The constructor for a UI node :param x: x position for the center of the node :param y: y position for the center of the node :param title: title of the node displayed in the ui :param parent: parent of this graphics item """ if title: self.title = title else: # give node a unique title self.title = "node {}".format(Node.i) self.id = model_node.id self.x = x self.y = y Node.i += 1 self.scene = scene self.model_node = model_node self.children = [] self.edges = [] # store node positional data when detaching from parent self.expand_data = None # add node name label centered in the eclipse, elide if title is too long self.node_text = QGraphicsSimpleTextItem() metrics = QFontMetrics(self.node_text.font()) elided_title = metrics.elidedText(self.title, Qt.ElideRight, self.NODE_MAX_WIDTH) self.node_text.setText(elided_title) self.node_text.setAcceptedMouseButtons(Qt.NoButton) self.node_text.setAcceptHoverEvents(False) self.text_width = self.node_text.boundingRect().width() self.text_height = self.node_text.boundingRect().height() self.node_text.setX(x - (self.text_width / 2)) # call super function now we know the node size super(Node, self).__init__(parent) self.node_text.setParentItem(self) # indicates if node is being dragged self.dragging = False self.setCursor(Qt.PointingHandCursor) self.setAcceptHoverEvents(True) # give the node a default color self.brush = QBrush(QColor(*self.NODE_COLOR)) self.simulator_brush = QBrush(self.DEFAULT_SIMULATOR_COLOR) # give node another color if node_types: # check for node types and color them types = node_types.get_node_type_by_name(model_node.title) if len(types) > 0: category, node_type = types[0] if category == 'decorators': self.brush.setColor(QColor(*self.DECORATOR_COLOR)) elif category == 'composites': self.brush.setColor(QColor(*self.COMPOSITE_COLOR)) else: self.brush.setColor(QColor(*self.OTHER_NODE_TYPES_COLOR)) # check for a strategy, role, tactic or keeper if 'name' in model_node.attributes.keys() or 'role' in model_node.attributes.keys(): if model_node.title == 'Tactic': self.brush.setColor(QColor(*self.TACTIC_COLOR)) elif model_node.title == 'Strategy': self.brush.setColor(QColor(*self.STRATEGY_COLOR)) elif model_node.title == 'Keeper': self.brush.setColor(QColor(*self.KEEPER_COLOR)) elif model_node.title == 'Role': self.brush.setColor(QColor(*self.ROLE_COLOR)) else: self.brush.setColor(QColor(*self.OTHER_SUBTREE_COLOR)) self.info_display = [] self.max_width = 0 self.total_height = 0 self.bottom_collapse_expand_button = None self.top_collapse_expand_button = None self._rect = None self.initiate_view()
class SongBriefLabel(QLabel): default_text = '...' def __init__(self, app): super().__init__(text=self.default_text, parent=None) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self._app = app # TODO: we can create a label class that roll the text when # the text is longer than the label width self._timer = QTimer() self._txt = self._raw_text = self.default_text self._font_metrics = QFontMetrics(QApplication.font()) self._text_rect = self._font_metrics.boundingRect(self._raw_text) # text's position, keep changing to make text roll self._pos = 0 self._timer.timeout.connect(self.change_text_position) self._fetching_artists = False def change_text_position(self): if not self.parent().isVisible(): self._timer.stop() self._pos = 0 return if self._text_rect.width() + self._pos > 0: # control the speed of rolling self._pos -= 5 else: self._pos = self.width() self.update() def setText(self, text): self._txt = self._raw_text = text self._text_rect = self._font_metrics.boundingRect(self._raw_text) self._pos = 0 self.update() def enterEvent(self, event): # we do not compare text_rect with self_rect here because of # https://github.com/feeluown/FeelUOwn/pull/425#discussion_r536817226 # TODO: find out why if self._txt != self._raw_text: # decrease to make rolling more fluent self._timer.start(150) def leaveEvent(self, event): self._timer.stop() self._pos = 0 self.update() def paintEvent(self, event): painter = QPainter(self) painter.setFont(QApplication.font()) painter.setPen(self._app.palette().color(self._app.palette().Text)) if self._timer.isActive(): self._txt = self._raw_text else: self._txt = self._font_metrics.elidedText(self._raw_text, Qt.ElideRight, self.width()) painter.drawText( QRect(self._pos, 0, self.width() - self._pos, self.height()), Qt.AlignLeft | Qt.AlignVCenter, self._txt) def contextMenuEvent(self, e): song = self._app.playlist.current_song if song is None: return menu = QMenu() menu.hovered.connect(self.on_action_hovered) artist_menu = menu.addMenu('查看歌手') album_action = menu.addAction('查看专辑') artist_menu.menuAction().setData({'artists': None, 'song': song}) album_action.triggered.connect( lambda: aio.create_task(self._goto_album(song))) if self._app.library.check_flags_by_model(song, ProviderFlags.similar): similar_song_action = menu.addAction('相似歌曲') similar_song_action.triggered.connect( lambda: self._app.browser.goto(model=song, path='/similar')) if self._app.library.check_flags_by_model(song, ProviderFlags.hot_comments): song_comments_action = menu.addAction('歌曲评论') song_comments_action.triggered.connect( lambda: self._app.browser.goto(model=song, path='/hot_comments')) menu.exec(e.globalPos()) async def _goto_album(self, song): album = await aio.run_in_executor( None, lambda: self._app.library.song_upgrade(song).album) self._app.browser.goto(model=album) def on_action_hovered(self, action): """ Fetch song.artists when artists_action is hovered. If it is already fetched, ignore. """ data = action.data() if data is None: # submenu action return def artists_fetched_cb(future): self._fetching_artists = False artists = future.result() # ignore the potential exception if artists: for artist in artists: artist_action = action.menu().addAction(artist.name) # create a closure to bind variable artist artist_action.triggered.connect( (lambda x: lambda: self._app.browser.goto(model=x) )(artist)) data['artists'] = artists or [] action.setData(data) # the action is artists_action if 'artists' in data: # artists value has not been fetched if data['artists'] is None and self._fetching_artists is False: logger.debug('fetch song.artists for actions') song = data['song'] self._fetching_artists = True task = aio.run_in_executor( None, lambda: self._app.library.song_upgrade(song).artists) task.add_done_callback(artists_fetched_cb)
def paint(self, painter, option, index): painter.save() painter.setRenderHint(QPainter.Antialiasing) rect = option.rect text_rect_height = 30 source_rect_height = TextHeight - text_rect_height cover_spacing = 0 text_y = rect.y() + rect.height() - TextHeight cover_height = rect.height() - TextHeight cover_width = rect.width() - cover_spacing cover_x = rect.x() + cover_spacing // 2 cover_y = rect.y() text_rect = QRectF(rect.x(), text_y, rect.width(), text_rect_height) source_rect = QRectF(rect.x(), text_y + text_rect_height - 5, rect.width(), source_rect_height + 5) obj = index.data(Qt.DecorationRole) if obj is None: painter.restore() return text_color = option.palette.color(QPalette.Text) if text_color.lightness() > 150: non_text_color = text_color.darker(140) else: non_text_color = text_color.lighter(150) non_text_color.setAlpha(100) painter.save() pen = painter.pen() pen.setColor(non_text_color) painter.setPen(pen) painter.translate(cover_x, cover_y) if isinstance(obj, QColor): color = obj brush = QBrush(color) painter.setBrush(brush) else: if obj.height() < obj.width(): pixmap = obj.scaledToHeight(cover_height, Qt.SmoothTransformation) else: pixmap = obj.scaledToWidth(cover_width, Qt.SmoothTransformation) brush = QBrush(pixmap) painter.setBrush(brush) border_radius = 3 if self.as_circle: border_radius = cover_width // 2 cover_rect = QRect(0, 0, cover_width, cover_height) painter.drawRoundedRect(cover_rect, border_radius, border_radius) painter.restore() option = QTextOption() source_option = QTextOption() if self.as_circle: option.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) source_option.setAlignment(Qt.AlignHCenter | Qt.AlignTop) else: option.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) source_option.setAlignment(Qt.AlignLeft | Qt.AlignTop) name = index.data(Qt.DisplayRole) fm = QFontMetrics(painter.font()) elided_name = fm.elidedText(name, Qt.ElideRight, text_rect.width()) source = index.data(Qt.WhatsThisRole) painter.drawText(text_rect, elided_name, option) painter.restore() painter.save() pen = painter.pen() font = painter.font() resize_font(font, -2) painter.setFont(font) pen.setColor(non_text_color) painter.setPen(non_text_color) painter.drawText(source_rect, source, source_option) painter.restore()
def config_tab_width(self): tab_stop = 2 metrics = QFontMetrics(self.font()) self.setTabStopWidth(tab_stop * metrics.width(' '))
def char_width_in_lineedit() -> int: char_width = QFontMetrics(QLineEdit().font()).averageCharWidth() # 'averageCharWidth' seems to underestimate on Windows, hence 'max()' return max(9, char_width)
class LineNumberArea(QWidget): def __init__(self, edit): #redraw lock self.locked = False super().__init__() self.lines = 0 self.width = 0 self.minWidth = 3 self.setMinimumSize(QSize(100, 15)) self.edit = edit self.font = self.edit.font() self.fm = QFontMetrics(self.font) self.fontHeight = self.fm.height() self.fontWidth = self.fm.width('0') self.adjustWidth(1) def adjustWidth(self, lines): newWidth = len(str(lines)) if newWidth < self.minWidth: self.width = self.minWidth else: self.width = newWidth self.baseWidth = self.width*self.fontWidth self.setFixedWidth(self.width*self.fontWidth) self.repaint() def paintEvent(self, QPaintEvent): if self.locked: return self.locked = True self.lines = self.edit.document().blockCount() qp = QPainter() super().paintEvent(QPaintEvent) qp.begin(self) s = self.size() h, w = s.height(), s.width() qp.setPen(QColor('#888')) #margin = 3 #fln = self.edit.verticalScrollBar().value() qp.setFont(self.font) block = self.edit.firstVisibleBlock() i = block.blockNumber() while block.isValid(): i += 1 ln = str(i) offset = self.baseWidth - self.fm.width(ln) y = self.edit.blockBoundingGeometry(block).translated(self.edit.contentOffset()).top() y += + self.fontHeight - 1 # check if on the screen yet if y >= QPaintEvent.rect().top(): qp.drawText(offset, y, ln) # check if out of the screen already if y >= QPaintEvent.rect().bottom(): break block = block.next() qp.end() self.locked = False