def paintEvent(self, event): painter = QPainter(self) if self.pixmap: painter.drawPixmap(0, 0, self.pixmap) margin = 25 pad = 10 if self.objectPlan: txt = self.objectPlan fm = QFontMetrics(painter.font()) rect = fm.boundingRect(txt) rect = fm.boundingRect(rect, 0, txt) rect.adjust(-pad, -pad, pad, pad) imageDir = self.config.get("display", "image_dir", fallback="images") iconPath = os.path.join(imageDir, 'text-x-generic.svg') icon = QIcon(iconPath) iconSize = icon.actualSize(rect.size()) rect.adjust(0, 0, iconSize.width(), 0) rect.moveBottomLeft(QPoint(margin, self.height() - margin)) painter.fillRect(rect, QColor(220, 220, 150, 225)) iconRect = QRect(rect) iconRect.setWidth(iconSize.width()) icon.paint(painter, iconRect) textRect = rect.adjusted(iconRect.width(), 0, 0, 0) painter.drawText(textRect, Qt.AlignCenter, txt)
def sizeHint(self, option: 'QStyleOptionViewItem', index: QModelIndex) -> QSize: if not index.isValid(): return QSize() playlist = index.model().at(index.row()) font = QApplication.font() title_fm = QFontMetrics(font) playlist_rec = title_fm.boundingRect(0, 0, option.rect.width() - PlaylistDelegate.icon_diameter, 0, Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, playlist.name) title_rect = title_fm.boundingRect(option.rect.left() + PlaylistDelegate.pad_horizontal, playlist_rec.bottom() + PlaylistDelegate.pad_vertical, playlist_rec.width(), 0, Qt.AlignHCenter | Qt.AlignTop | Qt.TextWordWrap, playlist.name) playlist_size = QSize(PlaylistDelegate.icon_diameter, playlist_rec.height() + PlaylistDelegate.pad_vertical + title_rect.height()) if playlist_size.height() < PlaylistDelegate.icon_diameter: playlist_size.setHeight(PlaylistDelegate.icon_diameter) return playlist_size
def getHeightHint(self, label_ref, pos): _text = '' if label_ref.text(): _doc = QTextDocument() _doc.setHtml(label_ref.text()) _text = _doc.toPlainText() fm = QFontMetrics(label_ref.font()) if label_ref.type == 'item_hint': fm_rect = QRect(*CFG.SIZE_ITEM_FULL()) _height = fm.boundingRect(fm_rect, Qt.TextWordWrap, _text).size().height() size = QSize(_height, _height) else: fm_rect = QRect( *CFG.SIZE_ITEM_FULL()) if not self.draw_image else QRect( *CFG.SIZE_ITEM_SIDE()) _height = fm.boundingRect(fm_rect, Qt.TextWordWrap, _text).size().height() size = QSize(0, _height) pass else: _height = min( label_ref.pixmap().height() + CFG.SIZE_IMG_ONLY_HEIGHT(self), CFG.SIZE_HISTORY_ITEM()[1]) size = QSize(_height, 0) pass return size
def paintEvent(self, event): painter = QPainter(self) if self.pixmap: painter.drawPixmap(0, 0, self.pixmap) rect = QRect(0, 0, self.width(), self.height()) margin = 25 pad = 10 if self.distance: txt = QLocale().toString(self.distance / 1000, 'f', 1) + ' km' fm = QFontMetrics(painter.font()) rect = fm.boundingRect(txt) rect = fm.boundingRect(rect, 0, txt) rect.adjust(-pad, 0, pad, 0) rect.moveBottomRight( QPoint(self.width() - margin, self.height() - margin)) if self.intersectsMarkers(rect): rect.moveTopRight(QPoint(self.width() - margin, margin)) painter.fillRect(rect, QColor(255, 255, 255, 192)) painter.drawText(rect, Qt.AlignCenter, txt) if self.duration: minutes = math.floor(self.duration / 60) seconds = self.duration - minutes * 60 txt = '%u:%02u min.' % (minutes, seconds) fm = QFontMetrics(painter.font()) rect = fm.boundingRect(txt) rect = fm.boundingRect(rect, 0, txt) rect.adjust(-pad, 0, pad, 0) rect.moveBottomLeft(QPoint(margin, self.height() - margin)) if self.intersectsMarkers(rect): rect.moveTopLeft(QPoint(margin, margin)) painter.fillRect(rect, QColor(255, 255, 255, 192)) painter.drawText(rect, Qt.AlignCenter, txt)
def boundText(self, qlabel): label = self.cleanhtml(qlabel.text()) metrics = QFontMetrics(self.font()) width = metrics.boundingRect(label).width() #width = metrics.boundingRect(label.text())#boundingRect(label.text()).width() #print(width) height = metrics.boundingRect(label).height() return QSize(width, height)
def paintEvent(self, event): super(DeviceCard, self).paintEvent(event) painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHints(QPainter.SmoothPixmapTransform) path = QPainterPath() # 绘制图标 c = 0 r = 0 margin = 0 if not self.hover_progress or self.hover_progress < 20: c = self.choking r = self.radius_x else: c = self.choking * (1 - self.getNolinearProg( self.hover_progress, NolinearType.SlowFaster if self.hovering else NolinearType.SlowFaster)) r = self.radius_x if self.radius_zoom < 0 else self.radius_x + ( self.radius_zoom - self.radius_x) * self.hover_progress / 100 rect = QRectF(10, 10, 80 - c * 2, 80 - c * 2) path.addRoundedRect(rect, 4, 4) painter.save() painter.setClipPath(path, Qt.IntersectClip) painter.drawPixmap(rect.x(), rect.y(), rect.width(), rect.height(), self.model.icon) painter.restore() # 绘制编号 fm = QFontMetrics(self.title_font) line_height = fm.lineSpacing() painter.setPen(self.title_color) painter.setFont(self.title_font) painter.drawText(QPoint(94 - c * 2, 36), self.model.sn) fm = QFontMetrics(self.body_font) line_height = fm.lineSpacing() painter.setPen(self.body_color) painter.setFont(self.body_font) f_rect = fm.boundingRect(QRect(94 - c * 2, 30 + line_height, 0, 0), Qt.TextSingleLine, self.model.name) painter.drawText(f_rect, Qt.TextSingleLine, self.model.name) f_rect = fm.boundingRect(QRect(94 - c * 2, 46 + line_height, 0, 0), Qt.TextSingleLine, self.model.active) painter.drawText(f_rect, Qt.TextSingleLine, self.model.active) # 状态位置 self.tag.move(220 - self.tag.tag_width() - 10 - c, 10)
def paint(self, painter, option, index): self.initStyleOption(option, index) painter.save() if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.highlight()) checkBox = QStyleOptionButton() checkBox.rect = self.getCheckBoxRect(option) checked = bool(index.model().data(index, roles['checked'])) if checked: checkBox.state |= QStyle.State_On else: checkBox.state |= QStyle.State_Off QApplication.style().drawControl(QStyle.CE_CheckBox, checkBox, painter) headerText = index.data(roles['from']) subjectText = index.data(roles['subject']) headerFont = QFont("times", 10) headerFont.setBold(True) subjectFont = QFont("times", 10) headerFm = QFontMetrics(headerFont) subjectFm = QFontMetrics(subjectFont) headerRect = headerFm.boundingRect( option.rect.left() + self.iconSize.width(), option.rect.top() + self.padding, option.rect.width() - self.iconSize.width(), 0, Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, headerText) subjectRect = subjectFm.boundingRect( headerRect.left(), headerRect.bottom() + self.padding, option.rect.width() - self.iconSize.width(), 0, Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, subjectText) painter.setPen(Qt.black) painter.setFont(headerFont) painter.drawText(headerRect, Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, headerText) painter.setFont(subjectFont) painter.drawText(subjectRect, Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, subjectText) painter.setPen(Qt.gray) painter.drawLine(option.rect.left(), option.rect.bottom(), option.rect.right(), option.rect.bottom()) painter.restore()
def paint(self, painter, option, widget=None): painter.setBrush(self._brush) painter.setPen(self.pen()) painter.drawRoundedRect(0, 0, self.nodeW, self.nodeH, self.radius, self.radius) painter.setPen(self._textPen) painter.setFont(self._nodeTextFont) metrics = QFontMetrics(painter.font()) text_width = metrics.boundingRect(self.nodeName).width() + 14 text_height = metrics.boundingRect(self.nodeName).height() + 14 margin = (text_width - self.nodeW) * 0.5 textRect = QRect(-margin, -text_height, text_width, text_height) painter.drawText(textRect, center, self.nodeName)
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 get_base_font_size(self): """Gets the base font size for all the UI elements. Returns: int: Base font size. """ self.__logger.info( "Calculating appropriated base font size for UI elements...") font_fits = False # Base font size will be calculated using self.label_password attribute font = self.label_password.font() font_size = font.pointSize() while not font_fits: fm = QFontMetrics(font) pixels_wide = fm.width(self.label_password.text()) pixels_high = fm.height() bound = fm.boundingRect(0, 0, pixels_wide, pixels_high, Qt.TextWordWrap | Qt.AlignLeft, self.label_password.text()) if bound.width() <= self.label_password.width() and \ bound.height() <= self.label_password.height(): font_fits = True else: font.setPointSize(font.pointSize() - 1) font_size = font_size - 1 self.__logger.info("Base font size = " + str(font_size)) return font_size
def paintText(self, text, color, fontSize, refX, refY, painter): ''' Paint text on top of the image and OpenGL drawings :param text: chars to write :param color: text color :param fontSize: text size in mm :param refX: position in reference units (mm of the real instrument). This is relative to the measurement unit position, NOT in pixels. :param refY: position in reference units (mm of the real instrument). This is relative to the measurement unit position, NOT in pixels. ''' prevPen = painter.pen() pPositionX = self.refToScreenX(refX) - (fontSize*self.scalingFactor*0.072) pPositionY = self.refToScreenY(refY) - (fontSize*self.scalingFactor*0.212) font = QFont('Bitstream Vera Sans') # Enforce minimum font size of 5 pixels fSize = max(5, int(fontSize*self.scalingFactor*1.26)) font.setPixelSize(fSize) metrics = QFontMetrics(font) border = max(4, metrics.leading()) rect = metrics.boundingRect(0, 0, self.width() - 2*border, int(self.height()*0.125), Qt.AlignLeft | Qt.TextWordWrap, text) painter.setPen(color) painter.setFont(font) painter.setRenderHint(QPainter.TextAntialiasing) painter.drawText(pPositionX, pPositionY, rect.width(), rect.height(), Qt.AlignCenter | Qt.TextWordWrap, text) painter.setPen(prevPen)
def sizeHint(self, option: 'QStyleOptionViewItem', index: QtCore.QModelIndex) -> QtCore.QSize: if not index.isValid(): return QSize() context = index.model().chat_message_contexts()[index.row()] msg_text = index.data(Qt.DisplayRole) msg_font = QApplication.font() msg_fm = QFontMetrics(msg_font) msg_rect = msg_fm.boundingRect( 0, 0, option.rect.width() - MessageItemDelegate.total_pfp_width + MessageItemDelegate.profile_padding, 0, Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, msg_text) msg_size = QSize( option.rect.width(), msg_rect.height() + MessageItemDelegate.padding + MessageItemDelegate.profile_padding) if msg_size.height() < MessageItemDelegate.icon_radius: msg_size.setHeight(MessageItemDelegate.icon_radius) return msg_size
def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget = None) -> None: super().paint(painter, option, widget) # write the label font = QFont() font.setBold(True) fm = QFontMetrics(font) label_text = self._label + '\n{0:.6g}'.format(self._duty) # measure the text height and width rect = fm.boundingRect(QApplication.desktop().geometry(), Qt.TextWordWrap | Qt.AlignCenter, label_text) label_width = rect.width() label_height = rect.height() # draw the text x = self.rect().x() y = self.rect().y() d = self._d mid_x = x + d * 0.5 mid_y = y + d * 0.5 painter.setFont(font) painter.drawText( QRectF(mid_x - 0.5 * label_width, mid_y - 0.5 * label_height, label_width, label_height), Qt.AlignCenter, label_text, )
def calculate_text_rect(text, font=None, painter=None, x=0, y=0, flag=Qt.TextSingleLine): if not painter and not font: return if painter: fm = QFontMetrics(painter.font()) rect = fm.boundingRect(QRect(x, y, 0, 0), flag, text) return rect if font: fm = QFontMetrics(font) rect = fm.boundingRect(QRect(x, y, 0, 0), flag, text) return rect
def drawTextLeftCenter(self, painter, text, pixelSize, x, y): self.font.setPixelSize(pixelSize) painter.setFont(self.font) metrics = QFontMetrics(self.font) bounds = metrics.boundingRect(text) painter.drawText(x, y - bounds.height() / 2, bounds.width(), bounds.height(), Qt.AlignLeft | Qt.TextDontClip, text)
def render_text(self, x, y, text, font=QFont('Arial', 50), color=Qt.white, h_align=Qt.AlignLeft, v_align=Qt.AlignBaseline): fm = QFontMetrics(font) fr = fm.boundingRect(text) if h_align == Qt.AlignRight: x -= fr.width() elif h_align == Qt.AlignHCenter or h_align == Qt.AlignCenter: x -= fr.width()/2 elif h_align == Qt.AlignLeft: pass else: print("WARNING: %r is not a valid option for horizontal text alignment. Set to Qt.AlignLeft." % h_align) if v_align == Qt.AlignTop: y += fm.ascent() elif v_align == Qt.AlignBottom: y -= fm.descent() elif v_align == Qt.AlignCenter or v_align == Qt.AlignVCenter: y += ((fr.height() / 2) - fm.descent()) elif v_align == Qt.AlignBaseline: pass else: print("WARNING: %r is not a valid option for vertical text alignment. Set to Qt.AlignBaseline." % v_align) painter = QPainter(self) painter.setPen(color) painter.setFont(font) painter.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing) painter.drawText(x, y, text) # z = pointT4.z + distOverOp / 4 painter.end()
def paintEvent(self, event): if self.btn_update: qp = QPainter() self.iconPix.fill(Qt.transparent) qp.begin(self.iconPix) self.text.setStyleSheet("#text { background: none; } ") self.text.setStyleSheet( "#text { background: rgba(155,150,100, 0); text-align: center; border-radius: 5px;} " ) if self.select: qp.setOpacity(.1) qp.setPen(Qt.NoPen) self.text.setStyleSheet( "#text { background: rgba(155,100,255, 0.5); text-align: center; border-radius: 5px;} " ) qp.setOpacity(self.opacity) self.drawIcon(event, qp) self.icon.setPixmap(self.iconPix) qp.end() QF = QFont() QFM = QFontMetrics(QF) bound = QFM.boundingRect(0, 0, 100, 1000, Qt.TextWordWrap | Qt.AlignCenter, self.text.text()) self.text.setFixedHeight(bound.height()) self.btn_update = False
def tabSizeHint(self, index): size = QTabBar.tabSizeHint(self, index) f = self.property('font') fm = QFontMetrics(f) w = fm.boundingRect(QRect(0, 0, 0, 0), Qt.AlignLeft, self.tabText(index)).width() return QSize(w + 30, size.height())
def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget = None) -> None: painter.setPen(self.pen()) shaft = self.line() x1 = shaft.x1() y1 = shaft.y1() x2 = shaft.x2() y2 = shaft.y2() # draw tips "knobs" painter.setRenderHint(QPainter.Antialiasing, True) painter.setBrush(self.pen().color()) k_radius = 5 # pixels painter.drawEllipse( QRectF(QPointF(x1 - k_radius, y1 - k_radius), QPointF(x1 + k_radius, y1 + k_radius))) painter.drawEllipse( QRectF(QPointF(x2 - k_radius, y2 - k_radius), QPointF(x2 + k_radius, y2 + k_radius))) painter.setBrush(Qt.NoBrush) painter.setRenderHint(QPainter.Antialiasing, False) # draw label circle in the middle of the shaft radius = self._ex_label_radius mid_x = 0.5 * (x1 + x2) left_x2 = mid_x - radius right_x2 = mid_x + radius painter.drawEllipse( QRectF(QPointF(left_x2, y1 - radius), QPointF(right_x2, y1 + radius))) # paint the line painter.drawLine(shaft.p1(), QPointF(left_x2, shaft.y1())) painter.drawLine(QPointF(right_x2, shaft.y1()), shaft.p2()) # write the label font = QFont() font.setBold(True) fm = QFontMetrics(font) label_text = self._label + '\n{0:.6g}'.format(self._duty) # measure the text height and width rect = fm.boundingRect(QApplication.desktop().geometry(), Qt.TextWordWrap | Qt.AlignCenter, label_text) label_width = rect.width() label_height = rect.height() # draw the text painter.setFont(font) painter.drawText( QRectF(mid_x - 0.5 * label_width, y1 - 0.5 * label_height, label_width, label_height), Qt.AlignCenter, label_text, )
def drawInstructions(self, painter): text = "Click and drag with the left mouse button to rotate the Qt " "logo." metrics = QFontMetrics(self.font()) border = max(4, metrics.leading()) rect = metrics.boundingRect( 0, 0, self.width() - 2 * border, int(self.height() * 0.125), Qt.AlignCenter | Qt.TextWordWrap, text, ) painter.setRenderHint(QPainter.TextAntialiasing) painter.fillRect( QRect(0, 0, self.width(), rect.height() + 2 * border), QColor(0, 0, 0, 127) ) painter.setPen(Qt.white) painter.fillRect( QRect(0, 0, self.width(), rect.height() + 2 * border), QColor(0, 0, 0, 127) ) painter.drawText( (self.width() - rect.width()) / 2, border, rect.width(), rect.height(), Qt.AlignCenter | Qt.TextWordWrap, text, )
def drawNode(painter, isSelected, node): rect = NodePainter.getNodeDim(node) if isSelected: painter.setPen(QPen(Qt.cyan, 3.0)) else: painter.setPen(Qt.black) painter.setBrush(Qt.gray) painter.drawRect(rect) for index, port in enumerate(node.data.inputs): NodePainter.drawPort(painter, False, index, node.data.getInput(index).value) # for index, port in enumerate(node.node.value): # NodePainter.drawPort(painter, False, index, node.data.getOutput(index)) NodePainter.drawPort(painter, True, 0, node.data.getOutput(0)) metrics = QFontMetrics(painter.font()) textBounds = metrics.boundingRect(node.title) painter.setPen(QColor(0, 0, 0, 128)) painter.setBrush(QColor(0, 0, 0, 128)) textRect = QRectF((rect.width() - textBounds.width()) / 2.0, (rect.height() - textBounds.height()) / 2.0 - 3.5, textBounds.width(), textBounds.height()) painter.drawText(textRect.bottomLeft(), node.title)
def drawTextCenterBottom(self, painter, text, pixelSize, x, y): self.font.setPixelSize(pixelSize) painter.setFont(self.font) metrics = QFontMetrics(self.font) bounds = metrics.boundingRect(text) painter.drawText(x - bounds.width() / 2, y, bounds.width(), bounds.height(), 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 set_node_wd_ht(self, nodes_to_recalc_dims): """set height and width attributes based on text properties""" # hm should it be so general that i don't have to run it every time? # question is if i recalculate all node properties if graph changes # depends on how expensive it is # either way should avoid multiple instantiations of fm_nt # also need to split up position assignment and height/width calculation logging.info('setting attributes') # font = ImageFont.truetype('Arial', self.font_size) # font = QFont("Arial", 12) font = QFont("Arial", self.font_size) fm = QFontMetrics(font) font = QFont("Arial", self.node_text_size) fm_nt = QFontMetrics(font) # font metric node text for n in nodes_to_recalc_dims: if self.g.nodes[n]['nd_tp'] == 'nd': node_rect = fm.boundingRect(self.g.nodes[n]['title']) nd_title_wd, nd_title_ht = node_rect.width(), node_rect.height() # get sizes of node body text lines nt_dims = self.get_node_text_dimensions(fm_nt, self.g.nodes[n]['node_text']) nt_dims[0].append(nd_title_wd) nt_dims[1].append(nd_title_ht) # node_sz = (node_rect.width() + self.wd_pad*2, node_rect.height()) # self.g.nodes[n]['width'] = node_sz[0] # self.g.nodes[n]['height'] = node_sz[1] self.g.nodes[n]['width'] = max(nt_dims[0]) + self.wd_pad*2 self.g.nodes[n]['height'] = sum(nt_dims[1]) logging.info(['node dims: ', self.g.nodes[n]['width'], self.g.nodes[n]['height']]) # if node is an edge label node there's no need to check for node text if self.g.nodes[n]['nd_tp'] == 'lbl': node_rect = fm_nt.boundingRect(self.g.nodes[n]['title']) nd_title_wd, nd_title_ht = node_rect.width(), node_rect.height() self.g.nodes[n]['width'] = nd_title_wd + self.wd_pad*2 self.g.nodes[n]['height'] = nd_title_ht self.dim_ar = np.array([[self.g.nodes[i]['width'], self.g.nodes[i]['height']] for i in self.g.nodes])
def render(self, qp, position): font = QFont('Consolas', 16) metrics = QFontMetrics(font) rect = metrics.boundingRect(self.text) qp.setFont(font) qp.drawText(QRect(position.x, position.y, rect.width(), rect.height()), Qt.AlignLeft, self.text)
def setText(self, text): self.m_text = text metrics = QFontMetrics(self.m_font) self.m_textRect = metrics.boundingRect(QRect(0, 0, 150, 150), Qt.AlignLeft, self.m_text) self.m_textRect.translate(5, 5) self.prepareGeometryChange() self.m_rect = self.m_textRect.adjusted(-5, -5, 5, 5)
def layout(self): cell_width = (self.rect.width()) / 7.0 cell_height = (self.rect.height() - 64) / 7.0 x = self.rect.left() y = self.rect.top() fm = QFontMetrics(self.header.font()) rect = fm.boundingRect(self.header.text()) self.header.setPos(x + self.rect.width() / 2 - rect.width() / 2, y) y += fm.height() for row, day in enumerate(self.weekdays): fm = QFontMetrics(day.font()) rect = fm.boundingRect(day.text()) day.setPos(x + row * cell_width + cell_width / 2 - rect.width() / 2, y) y += fm.height() self.header_line.setLine(x, y, x + self.rect.width() - 3, y) y += 8 for n, widget in enumerate(self.days): col = n % 7 row = n // 7 rect = fm.boundingRect(widget.text()) widget.setPos(x + col * cell_width + cell_width / 2 - rect.width() / 2, y + row * cell_height + cell_height / 2 - fm.height() / 2) # if day.month != self.now.month: # widget.setBrush(self.style.midcolor) # else: if self.cursor_pos is not None: self.cursor.setRect(x + self.cursor_pos[0] * cell_width, y + self.cursor_pos[1] * cell_height, cell_width, cell_height) self.cursor.show() else: self.cursor.hide()
def boundingRect(self): # Reimplementation of the boundingRect function, to resize the node based on the length of its title fm = QFontMetrics(QFont("Arial", 15)) text_size = fm.boundingRect(self.name + self.color_val_text) rect = self.rect() new_width = max(text_size.width(), rect.width()) new_height = text_size.height() return QRectF(rect.x(), rect.y(), new_width + 6, new_height + 10)
def getTextWidth(self, theText, theFont=None): """Returns the width needed to contain a given piece of text. """ if isinstance(theFont, QFont): qMetrics = QFontMetrics(theFont) else: qMetrics = QFontMetrics(self.guiFont) return int(ceil(qMetrics.boundingRect(theText).width()))
def paintEvent(self, event): ##在窗口上绘图 painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.TextAntialiasing) rect = QRect(0, 0, self.width(), self.height()) #viewport矩形区 painter.setViewport(rect) #设置Viewport painter.setWindow(0, 0, 120, 50) #设置窗口大小,逻辑坐标 ##绘制电池边框 pen = QPen() pen.setWidth(2) #线宽 pen.setColor(self.colorBorder) #划线颜色 pen.setStyle(Qt.SolidLine) #线的类型,实线、虚线等 pen.setCapStyle(Qt.FlatCap) #线端点样式 pen.setJoinStyle(Qt.BevelJoin) #线的连接点样式 painter.setPen(pen) brush = QBrush() #设置画刷 brush.setColor(self.colorBack) #画刷颜色 brush.setStyle(Qt.SolidPattern) #画刷填充样式 painter.setBrush(brush) rect.setRect(1, 1, 109, 48) painter.drawRect(rect) #绘制电池边框 brush.setColor(self.colorBorder) #画刷颜色 painter.setBrush(brush) rect.setRect(110, 15, 10, 20) painter.drawRect(rect) #画电池正极头 ##画电池柱 if self.__powerLevel > self.__warnLevel: #正常颜色电量柱 brush.setColor(self.colorPower) #画刷颜色 pen.setColor(self.colorPower) #划线颜色 else: ##电量低电量柱 brush.setColor(self.colorWarning) #画刷颜色 pen.setColor(self.colorWarning) #划线颜色 painter.setBrush(brush) painter.setPen(pen) if self.__powerLevel > 0: rect.setRect(5, 5, self.__powerLevel, 40) painter.drawRect(rect) #画电池柱 ##绘制电量百分比文字 textSize = QFontMetrics(self.font()) powStr = "%d%%" % self.__powerLevel textRect = QRect(textSize.boundingRect(powStr)) #得到字符串的rect painter.setFont(self.font()) pen.setColor(self.colorBorder) #划线颜色 painter.setPen(pen) painter.drawText(55 - textRect.width() / 2, 23 + textRect.height() / 2, powStr)
def intrinsicSize(self, doc: 'QTextDocument', pos_in_document: int, format_: 'QTextFormat') -> QtCore.QSizeF: charformat = format_.toCharFormat() font = charformat.font() fm = QFontMetrics(font) tag_name = format_.property(TagTextObject.name_propid) sz = fm.boundingRect(tag_name).size() sz.setWidth(sz.width() + 12) sz.setHeight(sz.height() + 4) return QtCore.QSizeF(sz)
def get_optimal_font(family_font: str, w, h, text: str) -> QFont: font = QFont(family_font) font.setStyleHint(QFont.Courier, QFont.PreferAntialias) metrics = QFontMetrics(font) # SOURCE: https://github.com/gil9red/SimplePyScripts/blob/add91e36e1ee59b3956b9fafdcffc9f4ff10ed3d/qt__pyqt__pyside__pyqode/pyqt__QPainter__draw_table.py#L98 factor = w / metrics.boundingRect(0, 0, w, h, Qt.AlignCenter, text).width() if factor < 1 or factor > 1.25: font.setPointSizeF(font.pointSizeF() * factor) return font
def __init__(self, parent=None): super(RenderArea, self).__init__(parent) newFont = self.font() newFont.setPixelSize(12) self.setFont(newFont) fontMetrics = QFontMetrics(newFont) self.xBoundingRect = fontMetrics.boundingRect("x") self.yBoundingRect = fontMetrics.boundingRect("y") self.shape = QPainterPath() self.operations = []
def layout(self): x = self.rect.left() y = self.rect.top() fm = QFontMetrics(self.time.font()) rect = fm.boundingRect("00:00") sfm = QFontMetrics(self.seconds.font()) self.time.setPos(x, y + 20) self.seconds.setPos(x + 20 + rect.width(), y + 20 + fm.ascent() - sfm.ascent()) self.label.setPos(x, y)
def _paintVertical(self, painter): """ Paint vertical scale """ fm = QFontMetrics(self._font) fwidth = 25 if self._flip: x0 = fwidth x1 = x0 + 3 x11 = x0 + 5 # x12 = 10 else: x0 = self.geometry().width() - fwidth x1 = x0 - 3 x11 = x0 - 5 x12 = x0 y0 = 0 y1 = self._scaleLenght() lbls = self._labels.replace(' ', '').split(',') if self._show_lines: # base line painter.drawLine(x0, y0, x0, y1) # cent lines for i in range(0, self._scaleLenght() + 1): pos = self._calcPos(self._scale_cent * i) painter.drawLine(x1, pos, x0, pos) for lbl in lbls: pos = self._calcPos(int(lbl)) painter.drawLine(x11, pos, x0, pos) # labels if self._show_labels: for lbl in self._labels.replace(' ', '').split(','): pos = self._calcPos(int(lbl)) if self._flip: x12 = (x0 - fm.boundingRect(lbl).width()) - 4 self._paintLabel(lbl, x12, pos, painter) # draw units label y = self._scaleLenght() + fm.height() + 1 pen = painter.pen() pen.setColor(pen.color().lighter(120)) painter.setPen(pen) painter.drawText( QPoint(x12, y), self._units )
def drawInstructions(self, painter): text = 'Press F1 for controls' metrics = QFontMetrics(QFont("Times", 12, QFont.Bold)) border = max(4, metrics.leading()) rect = metrics.boundingRect(0, 0, self.width() - 2*border, int(self.height()*0.125), Qt.AlignCenter, text) painter.setRenderHint(QPainter.TextAntialiasing) painter.fillRect(QRect(0, 0, self.width(), rect.height() + 2*border), QColor(0, 0, 0, 127)) painter.setPen(Qt.white) painter.fillRect(QRect(0, 0, self.width(), rect.height() + 2*border), QColor(0, 0, 0, 127)) painter.drawText((self.width() - rect.width())/2, border, rect.width(), rect.height(), Qt.AlignCenter | Qt.TextWordWrap, text)
def drawInstructions(self, painter): text = "Click and drag with the left mouse button to rotate the Qt " \ "logo." metrics = QFontMetrics(self.font()) border = max(4, metrics.leading()) rect = metrics.boundingRect(0, 0, self.width() - 2 * border, int(self.height() * 0.125), Qt.AlignCenter | Qt.TextWordWrap, text) painter.setRenderHint(QPainter.TextAntialiasing) painter.fillRect(QRect(0, 0, self.width(), rect.height() + 2 * border), QColor(0, 0, 0, 127)) painter.setPen(Qt.white) painter.fillRect(QRect(0, 0, self.width(), rect.height() + 2 * border), QColor(0, 0, 0, 127)) painter.drawText((self.width() - rect.width()) / 2, border, rect.width(), rect.height(), Qt.AlignCenter | Qt.TextWordWrap, text)
def axis_arrow(self, label, x0, x1, arrow_size): path = arrow(x0, x1, arrow_size) if not path: return QPainterPath() plan = self.plan font = QFont(plan.font()) font.setPointSize(14) metr = QFontMetrics(font) rect = metr.boundingRect(label) rect.setHeight(metr.xHeight()) tran = self.deviceTransform(self.plan.viewportTransform()).inverted()[0] size = tran.mapRect(QRectF(rect)).size() w, h = size.width(), size.height() dir_ = (x1 - x0) / np.linalg.norm(x1 - x0) offs = [-w/2, +h/2] + dir_ * max(w, h) path.addText(QPointF(*(x1 + offs)), font, label) return path
def create_font_array(self, char_height=62, pixel_margin=1, font_family='Courier', font_weight=50): # Load font and get the dimensions of one character (assuming monospaced font) f = QFont(font_family) f.setPixelSize(char_height) f.setWeight(font_weight) fm = QFontMetrics(f, QImage()) char_width = char_height = 0 char_y = 999 for i in range(32, 127): bb = fm.boundingRect(chr(i)) char_width = max(char_width, bb.width()) char_height = max(char_height, bb.height()) char_y = min(char_y, bb.y()) imgsize = (char_width + 2 * pixel_margin, char_height + 2 * pixel_margin) self.char_ar = float(imgsize[1]) / imgsize[0] # init the image and the painter that will draw the characters to each image img = QImage(imgsize[0], imgsize[1], QImage.Format_ARGB32) ptr = c_void_p(int(img.constBits())) painter = QPainter(img) painter.setFont(f) painter.setPen(QColor(255, 255, 255, 255)) # Set-up the texture array self.tex_id = gl.glGenTextures(1) gl.glBindTexture(gl.GL_TEXTURE_2D_ARRAY, self.tex_id) gl.glTexImage3D(gl.GL_TEXTURE_2D_ARRAY, 0, gl.GL_RGBA8, imgsize[0], imgsize[1], 127 - 32, 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, None) gl.glTexParameteri(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameteri(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameterf(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_BORDER) gl.glTexParameterf(gl.GL_TEXTURE_2D_ARRAY, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_BORDER) # We're using the ASCII range 32-126; space, uppercase, lower case, numbers, brackets, punctuation marks for i in range(32, 127): img.fill(0) painter.drawText(pixel_margin, pixel_margin - char_y, chr(i)) gl.glTexSubImage3D(gl.GL_TEXTURE_2D_ARRAY, 0, 0, 0, i - 32, imgsize[0], imgsize[1], 1, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, ptr) # We're done, close the painter, and return the texture ID, char width and char height painter.end()
class PBWToolTipInfo: def __init__(self, parent=None): self._visible = False self._x = 0 self._y = 0 self._text = '' self._bgcolor = QColor(0, 0, 0, 128) self._frame_color = QColor(0, 0, 0, 0) self._text_color = QColor(255, 255, 255) self._font = QFont('Tahoma', 8) self._fm = QFontMetrics(self._font) self._margin = 5 def set_font(self, font: QFont): self._font = font self._fm = QFontMetrics(self._font) def show_tt(self, x, y, text: str): self._visible = True self._x = x self._y = y self._text = text def hide(self): self._visible = False def isVisible(self): return self._visible def draw(self, painter: QPainter): if not self._visible: return bg_brush = QBrush(self._bgcolor, Qt.SolidPattern) b_rect = self._fm.boundingRect(self._text) b_rect.adjust(0, 0, self._margin, self._margin) b_rect.moveTo(self._x, self._y) painter.setPen(self._frame_color) painter.setBrush(bg_brush) painter.drawRect(b_rect) painter.setPen(self._text_color) painter.setFont(self._font) painter.drawText(b_rect, Qt.AlignCenter, self._text)
class Scale(QObject): def __init__(self, tick_text_font, title_text_font, parent): super().__init__(parent) self.axis_line_thickness = 1 # px, fixed self.tick_mark_thickness = 1 # px, fixed self.tick_mark_size_small = 5 # px, fixed self.tick_mark_size_medium = 7 # px, fixed self.tick_mark_size_large = 9 # px, fixed self.tick_text_font = tick_text_font self.tick_text_font_metrics = QFontMetrics(self.tick_text_font) self.tick_text_height = self.tick_text_font_metrics.boundingRect('0123456789').height() self.tick_text_height_half = int(round(self.tick_text_height / 2.0)) self.tick_text_half_digit_width = int(round(self.tick_text_font_metrics.width('0123456789') / 20.0)) self.tick_value_to_str = istr self.title_text_font = title_text_font self.title_text_font_metrics = QFontMetrics(self.title_text_font)
class PackageDelegate(QStyledItemDelegate): packageSelected=pyqtSignal([bool]) AppStyle = qApp.style def __init__(self, parent=None, mainWindow=None, showDetailsButton=True, animatable=True): super(PackageDelegate, self).__init__(parent) self.webDialog = WebDialog(mainWindow) self.show_details_button = showDetailsButton self.rowAnimator = RowAnimator(parent.packageList) self.defaultIcon = KIcon(('package-x-generic', 'package_applications'), 32) self.defaultInstalledIcon = QIcon(KIconLoader.loadOverlayed(('package-x-generic', 'package_applications'), CHECK_ICON, 32)) self.animatable = animatable self._max_height = ROW_HEIGHT self._rt_0 = QIcon(":/data/star_0.svg") self._rt_1 = QIcon(":/data/star_1.svg") self.types = {'critical':(RED, _translate("Packaga Manager",'critical')), 'security':(DARKRED, _translate("Packaga Manager",'security'))} self.font = Pds.settings('font','Sans,10').split(',')[0] self.normalFont = QFont(self.font, 10, QFont.Normal) self.boldFont = QFont(self.font, 11, QFont.Bold) self.normalDetailFont = QFont(self.font, 9, QFont.Normal) self.boldDetailFont = QFont(self.font, 9, QFont.Bold) self.tagFont = QFont(self.font, 7, QFont.Normal) self.tagFontFM = QFontMetrics(self.tagFont) self.boldFontFM = QFontMetrics(self.boldFont) self.boldDetailFontFM = QFontMetrics(self.boldDetailFont) self.normalFontFM = QFontMetrics(self.normalFont) self.normalDetailFontFM = QFontMetrics(self.normalDetailFont) self._titles = {'description': _translate("Packaga Manager","Description:"), 'website' : _translate("Packaga Manager","Website:"), 'release' : _translate("Packaga Manager","Release:"), 'repository' : _translate("Packaga Manager","Repository:"), 'size' : _translate("Packaga Manager","Package Size:"), 'installVers': _translate("Packaga Manager","Installed Version:")} self._titleFM = {} for key, value in self._titles.items(): self._titleFM[key] = self.boldDetailFontFM.width(value) + ICON_SIZE + 3 self.baseWidth = self.boldFontFM.width(max(self._titles.values(), key=len)) + ICON_SIZE self.parent = parent.packageList # Base style for some of important features # self.plastik = QStyleFactory.create('plastique') def paint(self, painter, option, index): if not index.isValid(): return super(PackageDelegate, self).paint(painter, option, index) if index.flags() & Qt.ItemIsUserCheckable: if index.column() == 0: self.paintCheckBoxColumn(painter, option, index) else: self.paintInfoColumn(painter, option, index) else: self.paintInfoColumn(painter, option, index, width_limit = 10) def paintCheckBoxColumn(self, painter, option, index): opt = QStyleOptionViewItem(option) buttonStyle = QStyleOptionButton() buttonStyle.state = QStyle.State_On if index.model().data(index, Qt.CheckStateRole) == QVariant(Qt.Checked) else QStyle.State_Off buttonStyle.state |= QStyle.State_Enabled if option.state & QStyle.State_MouseOver or option.state & QStyle.State_HasFocus: buttonStyle.state |= QStyle.State_HasFocus | QStyle.State_MouseOver buttonStyle.rect = opt.rect.adjusted(4, -opt.rect.height() + ROW_HEIGHT, 0, 0) PackageDelegate.AppStyle().drawControl(QStyle.CE_CheckBox, buttonStyle, painter, None) def paintInfoColumn(self, painter, option, index, width_limit = 0): left = option.rect.left() + 3 top = option.rect.top() width = option.rect.width() - width_limit pixmap = QPixmap(option.rect.size()) pixmap.fill(Qt.transparent) p = QPainter(pixmap) p.setRenderHint(QPainter.Antialiasing, True) p.translate(-option.rect.topLeft()) textInner = 2 * ICON_PADDING + ROW_HEIGHT - 10 itemHeight = ROW_HEIGHT + 2 * ICON_PADDING margin = left + ICON_PADDING - 10 title = QVariant.value(index.model().data(index, NameRole)) summary = QVariant.value(index.model().data(index, SummaryRole)) ptype = QVariant.value(index.model().data(index, TypeRole)) rate = int(QVariant.value(index.model().data(index, RateRole))) if QVariant.value(index.model().data(index, RateRole))!= None else 0 installed = True if QVariant.value(index.model().data(index, InstalledRole))=="True" else False # We need to request update if its not possible to get meta data about the package try: # Get Package Icon if exists _icon = QVariant.value(index.model().data(index, Qt.DecorationRole)) except: p.end() painter.drawPixmap(option.rect.topLeft(), pixmap) self.parent.requestUpdate() return icon = None if _icon: overlay = [CHECK_ICON] if installed else [] KIconLoader._forceCache = True pix = KIconLoader.loadOverlayed(_icon, overlay, 32) if not pix.isNull(): icon = QIcon(pix.scaled(QSize(32, 32), Qt.KeepAspectRatio, Qt.SmoothTransformation)) KIconLoader._forceCache = False if not icon: icon = self.defaultIcon if not installed else self.defaultInstalledIcon # Paint the Icon icon.paint(p, margin, top + ICON_PADDING, ROW_HEIGHT, ROW_HEIGHT, Qt.AlignCenter) fix_pos = 0 if index.model().columnCount() <= 1: fix_pos = 22 if config.USE_APPINFO: # Rating Stars for _rt_i in range(5): self._rt_0.paint(p, width + 10 * _rt_i - 30 - fix_pos, top + ROW_HEIGHT / 4, 10, 10, Qt.AlignCenter) for _rt_i in range(rate): self._rt_1.paint(p, width + 10 * _rt_i - 30 - fix_pos, top + ROW_HEIGHT / 4, 10, 10, Qt.AlignCenter) foregroundColor = option.palette.color(QPalette.Text) p.setPen(foregroundColor) # Package Name p.setFont(self.boldFont) p.drawText(left + textInner, top, width - textInner, itemHeight / 2,Qt.AlignBottom | Qt.AlignLeft, title) # tagWidth = 0 _component_width = 0 if self.parent.showComponents: component = str(QVariant.value(index.model().data(index, ComponentRole))) widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner p.setFont(self.tagFont) rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, component) p.setPen(LIGHTGREEN) p.setBrush(LIGHTGREEN) p.drawRoundedRect(widthOfTitle , top + 12, rect.width() + 4, rect.height(), 10, 10) p.setPen(DARKGREEN) p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, component) p.setPen(foregroundColor) _component_width = rect.width() + 8 if self.parent.showIsA: isa = str(QVariant.value(index.model().data(index, IsaRole))) if not isa == '': widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner + _component_width p.setFont(self.tagFont) rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, isa) p.setPen(LIGHTBLUE) p.setBrush(LIGHTBLUE) p.drawRoundedRect(widthOfTitle , top + 12, rect.width() + 4, rect.height(), 10, 10) p.setPen(DARKVIOLET) p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, isa) p.setPen(foregroundColor) _component_width += rect.width() + 8 if ptype not in ('None', 'normal'): widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner + _component_width p.setFont(self.tagFont) rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, self.types[ptype][1]) p.setPen(self.types[ptype][0]) p.setBrush(self.types[ptype][0]) p.drawRoundedRect(widthOfTitle, top + 12, rect.width() + 4, rect.height(), 10, 10) p.setPen(WHITE) p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, self.types[ptype][1]) p.setPen(foregroundColor) tagWidth = rect.width() # Package Summary p.setFont(self.normalFont) foregroundColor.setAlpha(160) p.setPen(foregroundColor) elided_summary = self.normalFontFM.elidedText(summary, Qt.ElideRight, width - textInner - tagWidth - 22) p.drawText(left + textInner, top + itemHeight / 2, width - textInner, itemHeight / 2, Qt.TextDontClip, elided_summary) foregroundColor.setAlpha(255) p.setPen(foregroundColor) buttonStyle = None if self.rowAnimator.currentRow() == index.row(): description = str(QVariant.value(index.model().data(index, DescriptionRole))) size = str(QVariant.value(index.model().data(index, SizeRole))) homepage = str(QVariant.value(index.model().data(index, HomepageRole))) installedVersion = str(QVariant.value(index.model().data(index, InstalledVersionRole))) version = str(QVariant.value(index.model().data(index, VersionRole))) # Package Detail Label position = top + ROW_HEIGHT p.setFont(self.normalDetailFont) baseRect = QRect(left, position, width - 8, option.rect.height()) rect = self.normalDetailFontFM.boundingRect(baseRect, Qt.TextWordWrap | Qt.TextDontClip, description) p.drawText(left + 2, position, width - 8, rect.height(), Qt.TextWordWrap | Qt.TextDontClip, description) # Package Detail Homepage position += rect.height() + 4 p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['website']) p.setFont(self.normalDetailFont) homepage = self.normalDetailFontFM.elidedText(homepage, Qt.ElideRight, width - self._titleFM['website']) rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextSingleLine, homepage) self.rowAnimator.hoverLinkFilter.link_rect = QRect(left + self._titleFM['website'] + 2, position + 2 + 32, rect.width(), rect.height()) p.setPen(option.palette.color(QPalette.Link)) p.drawText(left + self._titleFM['website'], position, width, rect.height(), Qt.TextSingleLine, homepage) p.setPen(foregroundColor) # Package Detail Version position += rect.height() p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['release']) p.setFont(self.normalDetailFont) rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextWordWrap, version) p.drawText(left + self._titleFM['release'], position, width, rect.height(), Qt.TextWordWrap, version) if not installedVersion == '' or not installedVersion == None: position += rect.height() p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['installVers']) p.setFont(self.normalDetailFont) rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextWordWrap, installedVersion) p.drawText(left + self._titleFM['installVers'], position, width, rect.height(), Qt.TextWordWrap, installedVersion) # Package Detail Repository repository = QVariant.value(index.model().data(index, RepositoryRole)) if not repository == '': repository = _translate("Packaga Manager",'Unknown') if repository == 'N/A' else repository position += rect.height() p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['repository']) p.setFont(self.normalDetailFont) p.drawText(left + self._titleFM['repository'], position, width, itemHeight / 2, Qt.TextWordWrap, repository) # Package Detail Size position += rect.height() p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['size']) p.setFont(self.normalDetailFont) p.drawText(left + self._titleFM['size'], position, width, itemHeight / 2, Qt.TextWordWrap, size) position += rect.height() self.rowAnimator.max_height = position - top + 8 # Package More info button opt = QStyleOptionViewItem(option) buttonStyle = QStyleOptionButton() if option.state & QStyle.State_MouseOver or option.state & QStyle.State_HasFocus: buttonStyle.state |= QStyle.State_HasFocus buttonStyle.state |= QStyle.State_Enabled buttonStyle.text = _translate("Packaga Manager","Details") buttonStyle.rect = QRect(width - 100, position - 22, 100, 22) p.end() # FIXME # if option.state & QStyle.State_HasFocus and self.animatable: # option.state |= QStyle.State_MouseOver # Use Plastique style to draw focus rect like MouseOver effect of Oxygen. # self.plastik.drawPrimitive(QStyle.PE_FrameLineEdit, option, painter, None) if not self.rowAnimator.running() and buttonStyle: if self.show_details_button and (installed or config.USE_APPINFO): PackageDelegate.AppStyle().drawControl(QStyle.CE_PushButton, buttonStyle, painter, None) self.rowAnimator.hoverLinkFilter.button_rect = QRect(buttonStyle.rect) painter.drawPixmap(option.rect.topLeft(), pixmap) del pixmap def editorEvent(self, event, model, option, index): #paket seçim olayında hata var seçim olayı gerçekleşiyor ama packageList sonraki seçimde görüyor #geçici çözümle giderildi tamamen çözülmeli if event.type() == QEvent.MouseButtonRelease and index.column() == 0 and index.flags() & Qt.ItemIsUserCheckable: toggled = Qt.Checked if model.data(index, Qt.CheckStateRole) == QVariant(Qt.Unchecked) else Qt.Unchecked self.packageSelected.emit(bool(toggled)) return model.setData(index, toggled, Qt.CheckStateRole) __event = QItemDelegate(self).editorEvent(event, model, option, index) animate_requested = False if event.type() == QEvent.MouseButtonRelease and self.animatable: if self.rowAnimator.row == index.row(): epos = event.pos() if self.rowAnimator.hoverLinkFilter.link_rect.contains(QPoint(epos.x(), epos.y() + 32)): url = QUrl(QVariant.value(model.data(index, HomepageRole))) QDesktopServices.openUrl(url) return __event elif self.rowAnimator.hoverLinkFilter.button_rect.contains(epos, True): self.showPackageDetails(model, index) return __event animate_requested = True elif event.type() == QEvent.KeyPress and self.animatable: # KeyCode 32 : Space key if event.key() == 32 and index.column() == index.model().columnCount() - 1: animate_requested = True if not QVariant.value(model.data(index, DescriptionRole)) == '' and animate_requested: self.rowAnimator.animate(index.row()) return __event def showPackageDetails(self, model, index): def _getter(role): return model.data(index, role) name = _getter(NameRole) summary = _getter(SummaryRole) description = _getter(DescriptionRole) installed = True if str(QVariant.value(model.data(index, InstalledRole)))=="True" else False self.webDialog.showPackageDetails(name, installed, summary, description) def sizeHint(self, option, index): if self.rowAnimator.currentRow() == index.row() and not index.row() == 0: return self.rowAnimator.size() else: width = ICON_SIZE if index.column() == 0 else 0 return QSize(width, ROW_HEIGHT) def setAnimatable(self, animatable): self.animatable = animatable def reset(self): self.rowAnimator.reset()
class KnobWidget(QWidget): STYLE_ROUND = 1 STYLE_NEEDLE = 2 def __init__(self, parent=None): super().__init__(parent) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.minimum_value = -100 self.maximum_value = 100 self.value_range = self.maximum_value - self.minimum_value self.total_angle = 200 # degree self.pressed = False self.scale_visible = True self.scale_arc_visible = True self.scale_text_visible = True self.scale_step_size = 10 self.scale_step_divisions = 2 self.knob_radius = 20 # px self.knob_style = KnobWidget.STYLE_ROUND self.dynamic_resize = False self.dynamic_knob_radius = None self.needle_base_radius = 7 # px self.needle_color = Qt.red self.knob_to_scale = 4 # px self.knob_scaleless_to_border = 1 # px, applied if scale not visible self.base_color = QColor(245, 245, 245) self.base_color_pressed = Qt.red self.mark_color = Qt.black self.border_color = QColor(190, 190, 190) self.tick_size_large = 9 # px self.tick_size_small = 5 # px self.tick_to_text = 4 # px self.text_to_border = 2 # px self.text_radius = None self.title_text = None self.value = self.value_range / 2 self.value_factor = float(self.value - self.minimum_value) / self.value_range self.font_metrics = QFontMetrics(self.font()) self.recalculate_size() # override QWidget.resizeEvent def resizeEvent(self, event): QWidget.resizeEvent(self, event) self.recalculate_size() # override QWidget.paintEvent # Disable pylint warning for knob_radius (which can not be None, as it is read from # self.dynamic_knob_radius if self.dynamic_resize, which, when set first recalculates # the dynamic_knob_radius, and then calls update #pylint: disable=invalid-unary-operand-type def paintEvent(self, _event): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) width = self.width() height = self.height() if self.dynamic_resize: knob_radius = self.dynamic_knob_radius else: knob_radius = self.knob_radius # ensure that the center point is in the middle of a pixel to ensure # that exact vertial and horizantal ticks are drawn exactly 1px wide x = math.floor(width / 2.0) + 0.5 y = math.floor(height / 2.0) + 0.5 if DEBUG: painter.fillRect(0, 0, width, height, Qt.yellow) painter.translate(x, y) if self.knob_style == KnobWidget.STYLE_NEEDLE: r = min(x, y) - 1 painter.setPen(Qt.white) painter.setBrush(Qt.white) painter.drawEllipse(QPoint(0, 0), r, r) angle = self.value_factor * self.total_angle - (self.total_angle / 2.0) # draw base knob or needle spike if self.knob_style == KnobWidget.STYLE_ROUND: painter.setPen(self.border_color) if self.pressed: gradient = QRadialGradient(0, 0, knob_radius) gradient.setColorAt(0, self.base_color_pressed) gradient.setColorAt(0.85, self.base_color) gradient.setColorAt(1, self.base_color) painter.setBrush(gradient) else: painter.setBrush(self.base_color) painter.drawEllipse(QPoint(0, 0), knob_radius, knob_radius) elif self.knob_style == KnobWidget.STYLE_NEEDLE: painter.save() painter.rotate(angle) painter.setPen(self.needle_color) painter.setBrush(self.needle_color) needle = QPolygonF() needle.append(QPointF(self.needle_base_radius * 0.6, 0)) needle.append(QPointF(0, -knob_radius)) needle.append(QPointF(-self.needle_base_radius * 0.6, 0)) painter.drawPolygon(needle) painter.restore() # draw knob mark or needle base if self.knob_style == KnobWidget.STYLE_ROUND: painter.save() painter.rotate(angle) painter.setPen(QPen(self.mark_color, 2)) painter.drawLine(0, -knob_radius * 0.4, 0, -knob_radius * 0.8) painter.restore() elif self.knob_style == KnobWidget.STYLE_NEEDLE: painter.setPen(self.border_color) painter.setBrush(self.base_color) painter.drawEllipse(QPoint(0, 0), self.needle_base_radius, self.needle_base_radius) if self.scale_visible: painter.setPen(Qt.black) # draw scale arc if self.scale_arc_visible: painter.drawArc(-knob_radius - self.knob_to_scale, -knob_radius - self.knob_to_scale, knob_radius * 2 + self.knob_to_scale * 2, knob_radius * 2 + self.knob_to_scale * 2, (90 + self.total_angle / 2) * 16, -self.total_angle * 16) # draw scale ticks def value_to_angle(value): return (float(value - self.minimum_value) / self.value_range) * self.total_angle - (self.total_angle / 2.0) value = self.minimum_value while value <= self.maximum_value: angle = value_to_angle(value) painter.save() painter.rotate(value_to_angle(value)) painter.drawLine(0, -knob_radius - self.knob_to_scale, 0, -knob_radius - self.knob_to_scale - self.tick_size_large) if self.scale_text_visible: p = painter.worldTransform().map(QPoint(0, -knob_radius - \ self.knob_to_scale - \ self.tick_size_large - \ self.tick_to_text - \ self.text_radius)) painter.restore() if self.scale_text_visible: if DEBUG: painter.save() painter.setPen(QColor(255, 0, 0, 50)) painter.setBrush(QColor(255, 0, 0, 50)) painter.drawEllipse(QPoint(p.x() - x, p.y() - y), self.text_radius, self.text_radius) painter.restore() painter.drawText(p.x() - x - 30, p.y() - y - 30, 60, 60, Qt.TextDontClip | Qt.AlignHCenter | Qt.AlignVCenter, str(value)) for i in range(1, self.scale_step_divisions): sub_value = value + (float(self.scale_step_size) * i) / self.scale_step_divisions if sub_value > self.maximum_value: break painter.save() painter.rotate(value_to_angle(sub_value)) painter.drawLine(0, -knob_radius - self.knob_to_scale, 0, -knob_radius - self.knob_to_scale - self.tick_size_small) painter.restore() value += self.scale_step_size if self.title_text != None: painter.drawText(-knob_radius, knob_radius - 30, knob_radius * 2, 60, Qt.TextDontClip | Qt.AlignHCenter | Qt.AlignVCenter, self.title_text) def recalculate_size(self): if self.scale_visible: if self.scale_text_visible: text_width = 0 text_height = 0 value = self.minimum_value while value <= self.maximum_value: text_rect = self.font_metrics.boundingRect(str(value)) text_width = max(text_width, text_rect.width()) text_height = max(text_height, text_rect.height()) value += self.scale_step_size self.text_radius = math.sqrt((text_width / 2.0) ** 2 + (text_height / 2.0) ** 2) else: self.text_radius = 0 additional_radius = self.knob_to_scale + \ self.tick_size_large + \ self.tick_to_text + \ self.text_radius * 2 + \ self.text_to_border else: additional_radius = self.knob_scaleless_to_border diameter = (self.knob_radius + additional_radius) * 2 self.setMinimumSize(diameter, diameter) if self.dynamic_resize: radius = min(self.width(), self.height()) / 2 self.dynamic_knob_radius = radius - additional_radius def set_scale_visible(self, visible): self.scale_visible = visible self.recalculate_size() self.update() def set_scale_arc_visible(self, visible): self.scale_arc_visible = visible self.update() def set_scale_text_visible(self, visible): self.scale_text_visible = visible self.recalculate_size() self.update() def set_total_angle(self, total_angle): self.total_angle = max(min(total_angle, 360), 1) self.recalculate_size() self.set_value(self.value) def set_pressed(self, pressed): self.pressed = pressed self.update() def set_range(self, minimum_value, maximum_value): self.minimum_value = minimum_value self.maximum_value = maximum_value self.value_range = self.maximum_value - self.minimum_value self.recalculate_size() self.set_value(self.value) def set_knob_radius(self, radius): self.knob_radius = max(1, radius) self.recalculate_size() self.update() def set_knob_style(self, style): self.knob_style = style self.update() def set_dynamic_resize_enabled(self, enable): self.dynamic_resize = enable if self.dynamic_resize: self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) else: self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.recalculate_size() self.update() def set_scale(self, scale_step_size, scale_step_divisions): self.scale_step_size = max(EPSILON, scale_step_size) self.scale_step_divisions = scale_step_divisions self.recalculate_size() self.update() def set_title_text(self, text): self.title_text = text self.update() def set_value(self, value): self.value = max(min(value, self.maximum_value), self.minimum_value) self.value_factor = float(self.value - self.minimum_value) / self.value_range self.update() def get_value(self): return self.value
def blink_cursor(cls, textedit, color=None): """Highlights the cursor in a Q(Plain)TextEdit.""" metrics = QFontMetrics(textedit.textCursor().charFormat().font()) width = metrics.boundingRect("m").width() rect = textedit.cursorRect().normalized().adjusted(0, 0, width, 0) cls.blink(textedit, rect.translated(textedit.viewport().pos()), color)