0

There are a few related questions, such as

However none of them solved my problem.

Basically my situation is the following:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QLabel
from PyQt5.QtCore import QCoreApplication, Qt


class MyCustomWidget(QWidget):
    """I want to draw a border around instances of this class (but not its children)."""

    def __init__(self):
        super().__init__()
        layout = QHBoxLayout()
        layout.addWidget(QLabel('foo'))
        layout.addWidget(QLabel('bar'))
        self.setLayout(layout)

        # I want to draw a border around all instances of `MyCustomWidget`.
        # The following only applies the style sheet its children.
        self.setStyleSheet('border: 1px solid black;')
        
        # The following doesn't apply the style sheet to any object.
        self.setStyleSheet('.MyCustomWidget { border: 1px solid black; }')

        # The following doesn't apply the style sheet to any object.
        self.setObjectName('custom')
        self.setStyleSheet('#custom { border: 1px solid black; }')


class MainWidget(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()
        layout.addWidget(QLabel('Title'))
        layout.addWidget(MyCustomWidget())
        self.setLayout(layout)


if __name__ == '__main__':
    QCoreApplication.setAttribute(Qt.AA_X11InitThreads)
    app = QApplication(sys.argv)
    main_window = QMainWindow()
    main_window.setCentralWidget(MainWidget())
    main_window.show()
    app.exec_()

In the final app, I want to have a border drawn around only instaces of MyCustomWidget (i.e. not its children). However none of the following attempts were successful:

  • self.setStyleSheet('border: 1px solid black;') -- This applied the style sheet only to the children.
  • self.setStyleSheet('.MyCustomWidget { border: 1px solid black; }') -- This was the solution I was hoping for, but it didn't apply the style sheet to any object (this answer mentions that the class name only exists inside a namespace which must be specified as well, but I couldn't find it, as the className method doesn't seem to exist in PyQt5).
  • self.setObjectName('custom'); self.setStyleSheet('#custom { border: 1px solid black; }') -- Judging from the documentation, this should work as well, but for some reason it doesn't. Also it would be inconvenient to come up with artificial object names for the instances of MyCustomWidget only to apply the same style sheet to each of them. That's exactly what a class selector is for.

Does anyone know how to solve this, preferably by using a class selector in the style sheet?


$ python -m pip freeze | grep PyQt5
PyQt5==5.15.4
PyQt5-Qt5==5.15.2
PyQt5-sip==12.9.0
$ python --version
Python 3.9.5
eyllanesc
  • 221,139
  • 17
  • 121
  • 189
a_guest
  • 30,279
  • 8
  • 49
  • 99
  • Does this work for you? https://stackoverflow.com/questions/38958873/a-simple-subclass-of-qwidget-doesnt-work-as-a-qwidget. The first solution should have painted the widget as well, so I'm thinking it might be subclassing problem – Minh Jul 30 '21 at 11:06

0 Answers0