'PySide2 setStyle not applying to QTabBar

For some reason when I apply run setStyleSheet to a parent widget or to the QApplication instance, setStyle no longer works on QTabBar.

Here's a reproduction:

from PySide2 import QtWidgets


class _Style(QtWidgets.QProxyStyle):
    pass


application = QtWidgets.QApplication([])

widget = QtWidgets.QTabWidget()
widget.setStyleSheet("QLabel { color: green; }")  # <-- Remove this line and it works
widget.tabBar().setStyle(_Style(parent=widget.tabBar()))
print('Is the custom style', isinstance(widget.tabBar().style(), _Style))

widget.show()

application.exec_()

If you run the code above, "Is the custom style" reports False If you comment out or remove widget.setStyleSheet("QLabel { color: green; }") and re-run it, "Is the custom style" reports True.

According to Qt's QStyle documentation:

A style can also be set on an individual widget using the setStyle() function.

When setStyleSheet is called, on either widget or application, widget.tabBar().style() is replaced with QCommonStyle. The intended class, _Style, gets completely unset.

How can I fix this so that "Is the custom style" reports True, even if a parent widget changes its style sheet?

Note:

Tested with PySide2-5.15.2.1 on both CentOS 7 and Windows 10



Solution 1:[1]

From setStyle,

Qt style sheets are currently not supported for custom QStyle subclasses. We plan to address this in some future release.

so it doesn't work like that.

But considering your goal, I guess this script could help you.

from PySide2 import QtWidgets

sheet = """

QLabel {
  color: green;
}

QTabBar > QLabel{
    color: black;
    font-style: italic;
}


QTabBar::tab:selected{
    background-color: orange;
}
QTabBar::tab:!selected{
    background-color:dodgerblue;
}

QTabBar > QLabel[failed="true"] {
    font-weight: bold;
    font-style: normal;
}
"""


class CustomTabWidget(QtWidgets.QTabWidget):
    def addTab(self, widget, title, warning=False):
        index = super().addTab(widget, "")
        piece = QtWidgets.QLabel(text=title, parent=self.tabBar())
        piece.setProperty("failed", True) if warning else ...

        self.tabBar().setTabButton(index, QtWidgets.QTabBar.LeftSide, piece)

        return index


application = QtWidgets.QApplication([])

widget = CustomTabWidget()

widget.setStyleSheet(sheet)


widget.addTab(QtWidgets.QLabel("Hello, for test1"), "test1")
widget.addTab(QtWidgets.QLabel("Hello, for test2"), "test2")
widget.addTab(QtWidgets.QLabel("Hello, for test3"), "test3")
test4 = widget.addTab(QtWidgets.QLabel("Hello, for test4"), "test4", True)
print(test4)

widget.show()

application.exec_()

You can refer stylesheet guide here. And use dynamic properties to target that label in tab.

Though, it's not possible to target a tab at some index, so use a widget inside the tab and then change its properties.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rahul A Ranger