I'm trying to style my application though a QProxyStyle
.
I create a StyleCustom
class which override drawControl
to draw my tabs in red or green depending on the tab state, and add the text on top of it.
However, using option.text
gives me the following error :
AttributeError: 'PySide2.QtWidgets.QStyleOption' object has no attribute 'text'
I notice here that option
is a QStyleOption
when it should be a QStyleOptionTab if I'm not wrong.
If I comment the drawText
command, no crash, but the tabs are not colored as they should be :
I feel that somehow, the drawControl
method is not receiving the options correctly. I have noticed a similar behaviour when trying to draw other control types.
Here is a basic example using a 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_()
Generally the casting is done by default in PySide (and also in PyQt) but in this case it seems that not so a possible solution is to do it using 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)