drawControl 没有收到正确的 QStyleOption

drawControl not receiving correct QStyleOption

我正在尝试通过 QProxyStyle.

来设置我的应用程序的样式

我创建了一个 StyleCustom class 覆盖 drawControl 以根据选项卡状态将我的选项卡绘制为红色或绿色,并在其顶部添加文本。

但是,使用 option.text 会出现以下错误:

AttributeError: 'PySide2.QtWidgets.QStyleOption' object has no attribute 'text'

我注意到 optionQStyleOption,如果我没记错的话它应该是 QStyleOptionTab

如果我评论 drawText 命令,没有崩溃,但选项卡没有按应有的颜色着色:

我觉得 drawControl 方法没有正确接收选项。我在尝试绘制其他控件类型时注意到类似的行为。

这是一个使用 QTabWidget 的基本示例:

from PySide2 import QtWidgets, QtGui, QtCore

class StyleCustom(QtWidgets.QProxyStyle):

    def drawControl(self, element: QtWidgets.QStyle.ControlElement, option: QtWidgets.QStyleOption, painter: QtGui.QPainter, widget:QtWidgets.QWidget=None):
        if element == QtWidgets.QStyle.ControlElement.CE_TabBarTabLabel:
            if option.state == QtWidgets.QStyle.State_Selected:
                painter.save()
                painter.fillRect(option.rect, QtGui.QBrush("#ff0000"))
                painter.restore()
            else:
                painter.save()
                painter.fillRect(option.rect, QtGui.QBrush("#00ff00"))
                painter.restore()
            painter.drawText(option.rect, QtCore.Qt.AlignCenter, option.text)
        else:
            return super().drawControl(element, option, painter, widget)

class MyMainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.tab = QtWidgets.QTabWidget()
        self.widg_1 = QtWidgets.QWidget()
        self.widg_2 = QtWidgets.QWidget()
        self.setCentralWidget(self.tab)
        self.tab.addTab(self.widg_1, "test1")
        self.tab.addTab(self.widg_2, "test2")

if __name__=='__main__':
    app = QtWidgets.QApplication()
    app.setStyle(StyleCustom())
    window = MyMainWindow()
    window.show()
    app.exec_()

一般情况下,转换是在 PySide(以及 PyQt)中默认完成的,但在这种情况下似乎并非如此,因此一种可能的解决方案是使用 shiboken2 进行转换:

import shiboken2
from PySide2 import QtWidgets, QtGui, QtCore


class StyleCustom(QtWidgets.QProxyStyle):
    def drawControl(
        self,
        element: QtWidgets.QStyle.ControlElement,
        option: QtWidgets.QStyleOption,
        painter: QtGui.QPainter,
        widget: QtWidgets.QWidget = None,
    ) -> None:
        if element == QtWidgets.QStyle.ControlElement.CE_TabBarTabLabel:
            (cpp_pointer,) = shiboken2.getCppPointer(option)
            option_tab = shiboken2.wrapInstance(cpp_pointer, QtWidgets.QStyleOptionTab)

            painter.save()
            painter.fillRect(
                option_tab.rect,
                QtGui.QBrush(
                    "#ff0000"
                    if option_tab.state == QtWidgets.QStyle.State_Selected
                    else "#00ff00"
                ),
            )
            painter.restore()
            painter.drawText(option_tab.rect, QtCore.Qt.AlignCenter, option_tab.text)
        else:
            super().drawControl(element, option, painter, widget)