I use the Qt4.8 Python binding PySide (version 1.2.2 on Python 3.3 on Windows) and I see that QWidget
behaves different from QWidget
derived widgets like QDialog
, QLabel
or QMainWindow
when styling with stylesheets.
In particular I observe that the attribute WA_StyledBackground
must be set to show a border or a background image while a background color is set independently. In contrast for the other widgets this attribute has no influence, a border or background image is always shown. Overriding the paintEvent
method is also a possibility.
Example code:
from PySide import QtGui, QtCore
class MyWidget(QtGui.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def paintEvent(self, event):
opt = QtGui.QStyleOption()
opt.initFrom(self)
painter = QtGui.QStylePainter(self)
painter.drawPrimitive(QtGui.QStyle.PE_Widget, opt)
def display(w):
print(w.__class__.__name__)
w.setWindowTitle(w.__class__.__name__)
print(' WA_StyledBackground is {}'.format(w.testAttribute(QtCore.Qt.WA_StyledBackground)))
print(' autoFillBackground is {}'.format(w.autoFillBackground()))
w.setStyleSheet('border: 4px inset #515c84; border-radius: 9px; background-color: blue; background-image: url(test.png);')
w.resize(400, 400)
w.show()
app = QtGui.QApplication([])
w1 = QtGui.QMainWindow(flags=QtCore.Qt.Window)
display(w1) # works
w2 = QtGui.QDialog(f=QtCore.Qt.Window)
display(w2) # works
w3 = QtGui.QWidget(f=QtCore.Qt.Window)
w3.setAttribute(QtCore.Qt.WA_StyledBackground)
display(w3) # works only with the previous line uncommented
w4 = QtGui.QLabel('Text', f=QtCore.Qt.Window)
display(w4) # works
w5 = MyWidget(f=QtCore.Qt.Window)
display(w5) # works
app.exec_()
This topic is already discussed partly on StackOverflow. The accepted answer on Borders and background of QWidget aren't set by stylesheet suggests overriding paintEvent
, the accepted answer of How to set QWidget background color? suggests to set setAutoFillBackground
in case one uses the palette and PySide: QWidget does not draw background color suggests to just set the above mentioned WA_StyledBackground
. What is missing is the reason for the differences between QWidget
and derived widgets.
I find these differences a bit confusing:
- Why is
QWidget
behaving different from derived widgets likeQLabel
,...? - Why can
QWidget
in the natural state not display borders or background images but it does diplay background colors? - Is there a difference between setting attribute
WA_StyledBackground
and overriddingpaintEvent
in the described way? Which method would be preferred?
tl;dr - Use
QFrame
I won't attempt to guess at the reasoning that went into this design decision, but generally speaking
QWidget
is considered to be borderless. If you want your widget to have nice styled borders, then you should probably be using aQFrame
, which essentially just aQWidget
with the border styling capabilities that you're looking for.You'll note that a lot of widgets (such as the
QLabel
you've mentioned) actually inherit fromQFrame
rather than directly fromQWidget
.I can't speak authoritatively in regards to the
WA_StyledBackground
property.