我想在包装QLabel的QWidget周围显示一个边框(这是一个更复杂的小部件的练习)。我正在使用setStyleSheet来创建边框。当我手动执行此操作时,它按预期工作。但是,当我将代码移动到自己的类(从QWidget派生)时,填充是不同的,我无法弄清楚为什么。
import sys
from PyQt5.QtWidgets import QWidget, QLabel, QApplication, QMainWindow, QVBoxLayout
class WrappedLabel(QWidget):
def __init__(self, text=''):
super().__init__()
self.text = QLabel(text)
layout = QVBoxLayout()
layout.addWidget(self.text)
self.setLayout(layout)
self.setStyleSheet('padding: 2px; border: 2px solid red;')
class Shell(QMainWindow):
def __init__(self): # constructor
super().__init__() # call the parent's constructor
w = QWidget() # Create the main window content widget
self.setCentralWidget(w)
# First label
unwrapped_label = QLabel('This is a normal QLabel with a border and no padding.')
unwrapped_label.setStyleSheet('border: 2px solid gray; padding: 2px;')
# Second label
wrapped_label = QLabel('This QLabel is manually wrapped in a styled QWidget. ' +
'There is a slight indent compared to the normal QLabel due to padding.')
wrapped_layout = QVBoxLayout()
wrapped_layout.addWidget(wrapped_label)
manual_wrapper = QWidget()
manual_wrapper.setObjectName('wrapper')
manual_wrapper.setLayout(wrapped_layout)
self.setStyleSheet('QWidget#wrapper { border: 2px solid gray; padding: 2px; }')
# Third label
derived_wrapper = WrappedLabel('This class derives from QWidget and wraps a QLabel like above, but is indented even further and the border is in the wrong spot.')
vbox = QVBoxLayout()
vbox.addWidget(unwrapped_label)
vbox.addWidget(manual_wrapper)
vbox.addWidget(derived_wrapper)
vbox.addStretch(1) # Squish them together to better see the spacing
w.setLayout(vbox)
# Setup the rest of the main window appearance
self.setGeometry(300,300,640,180)
self.setWindowTitle('Testing wrapped labels')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
shell = Shell() # create and show the main window
sys.exit(app.exec_())
答案 0 :(得分:2)
首先,自定义类WrappedLabel
中的代码与手动窗口小部件中的代码不完全相同。对于手动窗口小部件,您要确保样式表仅应用于窗口小部件本身,而不是应用于QWidget#wrapper
的任何子窗口小部件。对于自定义类,您只需将样式表应用于WrappedLabel
实例,这将导致它cascade到其所有子窗口小部件(以及QLabel
实例)。这就是你的QLabel
实例以填充和红色边框结束的原因。
那为什么包装器不会发生同样的情况呢?显然,QWidget
的自定义基类默认拒绝所有应用的样式表(请参阅this answer)。您可以在self.setAttribute(QtCore.Qt.WA_StyledBackground)
中添加WrappedLabel.__init__
来完成此工作。现在,您将看到最终有两个边框,一个用于包装,另一个用于标签。要将样式表限制为包装器,您需要应用与手动窗口小部件类似的标识符:self.setStyleSheet('WrappedLabel { padding: 2px; border: 2px solid red; }')
。
为了使其有效,您可以将其添加到WrappedLabel.__init__
:
self.setAttribute(QtCore.Qt.WA_StyledBackground)
self.setStyleSheet('WrappedLabel { padding: 2px; border: 2px solid red; }')