def drawControl(self, p, opt, arect, icon, menustyle): """ due to overrides the "paintEvent" method, so we must repaint all menu item by self. luckly, we have qt source code to reference. void drawControl (ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const https://cep.xray.aps.anl.gov/software/qt4-x11-4.8.6-browser/df/d91/class_q_style_sheet_style.html#ab92c0e0406eae9a15bc126b67f88c110 Line 3533: element = CE_MenuItem """ style = self.style() p.setPen(menustyle.getPenColor(opt)) # Line 3566: draw icon and checked sign checkable = opt.checkType != QStyleOptionMenuItem.NotCheckable checked = opt.checked if checkable else False if opt.icon.isNull() is False: # has custom icon dis = not (int(opt.state) & int(QStyle.State_Enabled)) active = int(opt.state) & int(QStyle.State_Selected) mode = QIcon.Disabled if dis else QIcon.Normal if active != 0 and not dis: mode = QIcon.Active fw = style.pixelMetric(QStyle.PM_MenuPanelWidth, opt, self) icone = style.pixelMetric(QStyle.PM_SmallIconSize, opt, self) iconRect = QRectF(arect.x() - fw, arect.y(), self._side_image.width(), arect.height()) if checked: pixmap = icon.pixmap(QSize(icone, icone), mode, QIcon.On) else: pixmap = icon.pixmap(QSize(icone, icone), mode) pixw = pixmap.width() pixh = pixmap.height() pmr = QRectF(0, 0, pixw, pixh) pmr.moveCenter(iconRect.center()) if checked: p.drawRect(QRectF(pmr.x() - 1, pmr.y() - 1, pixw + 2, pixh + 2)) p.drawPixmap(pmr.topLeft(), pixmap) elif checkable and checked: # draw default checked sign opt.rect = QRect(0, arect.y(), self._side_image.width(), arect.height()) opt.palette.setColor(QPalette.Text, menustyle.getPenColor(opt)) style.drawPrimitive(QStyle.PE_IndicatorMenuCheckMark, opt, p, self) # Line 3604: draw emnu text font = menustyle.font if font is not None: p.setFont(font) else: p.setFont(opt.font) text_flag = Qt.AlignVCenter | Qt.TextShowMnemonic | Qt.TextDontClip | Qt.TextSingleLine tr = QRect(arect) s = opt.text if '\t' in s: ss = s[s.index('\t') + 1:] fontwidth = opt.fontMetrics.width(ss) tr.moveLeft(opt.rect.right() - fontwidth) tr = QStyle.visualRect(opt.direction, opt.rect, tr) p.drawText(tr, text_flag, ss) tr.moveLeft(self._side_image.width() + arect.x()) tr = QStyle.visualRect(opt.direction, opt.rect, tr) p.drawText(tr, text_flag, s) # Line 3622: draw sub menu arrow if opt.menuItemType == QStyleOptionMenuItem.SubMenu: arrowW = style.pixelMetric(QStyle.PM_IndicatorWidth, opt, self) arrowH = style.pixelMetric(QStyle.PM_IndicatorHeight, opt, self) arrowRect = QRect(0, 0, arrowW, arrowH) arrowRect.moveBottomRight(arect.bottomRight()) arrow = QStyle.PE_IndicatorArrowLeft if opt.direction == Qt.RightToLeft else QStyle.PE_IndicatorArrowRight opt.rect = arrowRect opt.palette.setColor(QPalette.ButtonText, menustyle.getPenColor(opt)) style.drawPrimitive(arrow, opt, p, self) pass
def drawControl( self, element: QStyle.ControlElement, opt: Union[QStyleOption, QStyleOptionToolButton], p: QPainter, widget: QWidget, ): if element == QStyle.CE_ToolButtonLabel: toolbutton = opt rect = toolbutton.rect shift_x = 0 shift_y = 0 if toolbutton.state & (QStyle.State_Sunken | QStyle.State_On): # type: ignore shift_x = super(TTToolButtonStyle, self).pixelMetric( QStyle.PM_ButtonShiftHorizontal, toolbutton, widget ) shift_y = super(TTToolButtonStyle, self).pixelMetric( QStyle.PM_ButtonShiftVertical, toolbutton, widget ) has_arrow = bool(toolbutton.features & QStyleOptionToolButton.Arrow) # type: ignore if ( (not has_arrow and toolbutton.icon.isNull()) and toolbutton.text # type: ignore ) or toolbutton.toolButtonStyle == QtCore.Qt.ToolButtonTextOnly: # type: ignore alignment = ( QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter | QtCore.Qt.TextShowMnemonic ) if not self.proxy().styleHint(QStyle.SH_UnderlineShortcut, opt, widget): alignment |= QtCore.Qt.TextHideMnemonic rect.translate(shift_x, shift_y) p.setFont(toolbutton.font) # type: ignore self.proxy().drawItemText( p, rect, alignment, toolbutton.palette, bool(opt.state & QStyle.State_Enabled), # type: ignore toolbutton.text, # type: ignore QPalette.ButtonText, ) else: pm = QPixmap() pm_size = toolbutton.iconSize # type: ignore if not toolbutton.icon.isNull(): # type: ignore state = ( QIcon.On if (toolbutton.state & QStyle.State_On) else QIcon.Off # type: ignore ) mode = QIcon().Mode if not toolbutton.state & QStyle.State_Enabled: # type: ignore mode = QIcon.Disabled elif (opt.state & QStyle.State_MouseOver) and ( # type: ignore opt.state & QStyle.State_AutoRaise ): mode = QIcon.Active else: mode = QIcon.Normal pm = toolbutton.icon.pixmap( # type: ignore toolbutton.rect.size().boundedTo(toolbutton.iconSize), # type: ignore mode, state, ) pm_size = pm.size() if toolbutton.toolButtonStyle != QtCore.Qt.ToolButtonIconOnly: # type: ignore p.setFont(toolbutton.font) # type: ignore pr = QtCore.QRect(rect) tr = QtCore.QRect(rect) alignment = QtCore.Qt.TextShowMnemonic if not self.proxy().styleHint( QStyle.SH_UnderlineShortcut, opt, widget ): alignment |= QtCore.Qt.TextHideMnemonic if toolbutton.toolButtonStyle == QtCore.Qt.ToolButtonTextUnderIcon: # type: ignore pr.setHeight(pm_size.height() + 6) tr.adjust(0, pr.height() - 1, 0, -2) pr.translate(shift_x, shift_y) if not has_arrow: self.proxy().drawItemPixmap( p, pr, int(QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter), pm, ) alignment |= int(QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter) else: pr.setWidth(pm_size.width() + 8) tr.adjust(pr.width(), 0, 0, 0) pr.translate(shift_x, shift_y) if not has_arrow: self.proxy().drawItemPixmap( p, QStyle.visualRect(opt.direction, rect, pr), QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter, pm, ) alignment |= int(QtCore.Qt.AlignTop) | int( QtCore.Qt.AlignHCenter ) tr.translate(shift_x, shift_y) self.proxy().drawItemText( p, QStyle.visualRect(opt.direction, rect, tr), alignment, toolbutton.palette, bool(toolbutton.state & QStyle.State_Enabled), # type: ignore toolbutton.text, # type: ignore QPalette.ButtonText, ) else: rect.translate(shift_x, shift_y) if not has_arrow: self.proxy().drawItemPixmap( p, rect, QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter, pm ) return super(TTToolButtonStyle, self).drawControl(element, opt, p, widget)