示例#1
0
    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
示例#2
0
    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)