19

Case 1: Create subclass of QWidget with Q_OBJECT and set stylesheet -- no effect.

Case 2: Create subclass of QWidget without Q_OBJECT and set stylesheet -- works as expected

Case 3: Create subclass of QLabel with Q_OBJECT and set stylesheet -- works as expected

How to understand this behavior? Is it possible to make stylesheets work in the case 1?

user7797
  • 337
  • 3
  • 8
  • post some code pls, because from what you told us, there is only one way to understood this behaviour - you have something wrong in your code. Case 1 works just fine without any 'special technique' – evilruff Aug 20 '13 at 20:23

2 Answers2

30

If you want custom QWidget subclasses to support stylesheets, you need to provide the following code: Qt Code:

void myclass::paintEvent(QPaintEvent *pe)
{                                                                                                                                        
  QStyleOption o;                                                                                                                                                                  
  o.initFrom(this);                                                                                                                                                                
  QPainter p(this);                                                                                                                                                                
  style()->drawPrimitive(
    QStyle::PE_Widget, &o, &p, this);                                                                                                                         
};

Courtesy of wysota, as well as Qt help.

When you don't provide Q_OBJECT, your class has no Meta data, and hence is considered as a QWidget.

Werner Erasmus
  • 3,988
  • 17
  • 31
  • 1
    According to the Qt help files, "Every widget displaying custom content must implement the paintEvent". I can only guess that by default Qt's style mechanism that draws the control (QStyle::drawControl) performs some default painting for QWidgets (as identified by meta data as result of Q_OBJECT in QWidget). As soon as you provide Q_OBJECT for your own widget derivative, the default behaviour does not hold anymore, and Qt's drawControl begins to rely on code within paintEvent to draw the control. I must admit the help files does not specify why, but only that it is required. – Werner Erasmus Aug 21 '13 at 06:40
  • 1
    Direct subclasses of `QWidget` still need that `paintEvent()` override even if you provide `Q_OBJECT`. – Paulo Carvalho Aug 10 '17 at 12:21
  • This is also mentioned in this [wiki](https://wiki.qt.io/How_to_Change_the_Background_Color_of_QWidget#Using_Style_Sheet). – Fredrick Gauss Dec 20 '17 at 07:02
7

I don't know why they don't work, but I translated to python the code in Werner Erasmus's answer. The following "works for me"™

def paintEvent(self, pe):

    o = QStyleOption()
    o.initFrom(self)
    p = QPainter(self)
    self.style().drawPrimitive(QStyle.PE_Widget, o, p, self)
White_Rabbit
  • 115
  • 2
  • 7
  • Not working for me anymore in PyQt6 :( And you need to change the call to the PE_Widget enumeration `QStyle.PrimitiveElement.PE_Widget` – Spencer Oct 16 '22 at 05:18