代码之家  ›  专栏  ›  技术社区  ›  pediatrictactic

自定义类中包装的QLabel上出现意外填充

  •  3
  • pediatrictactic  · 技术社区  · 6 年前

    我想在包装QLabel的QWidget周围显示一个边框(这是一个更复杂的小部件的实践)。我正在使用setStyleSheet创建边框。当我手动执行此操作时,它按预期工作。然而,当我将代码移动到它自己的类(从QWidget派生)中时,填充是不同的,我不知道为什么。

    Output of code example

    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_())
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   a_guest    6 年前

    首先,自定义类中的代码 WrappedLabel 与手动小部件不完全相同。对于手动小部件,请确保样式表仅应用于小部件本身,而不是通过 QWidget#wrapper . 对于自定义类,只需将样式表应用于 包装标签 实例,该实例将导致 cascade 它的所有子窗口小部件(以及 QLabel 实例)。这就是为什么你 QLabel公司 实例以填充和红色边框结束。

    那么,为什么包装器没有发生同样的情况呢?显然是自定义基类 QWidget s默认情况下拒绝所有应用的样式表(请参见 this answer ). 您可以通过添加 self.setAttribute(QtCore.Qt.WA_StyledBackground) 在里面 WrappedLabel.__init__ . 现在,您将看到最终有两个边框,一个用于包装,一个用于标签。要将样式表限制为包装器,需要应用与手动小部件类似的标识符: self.setStyleSheet('WrappedLabel { padding: 2px; border: 2px solid red; }') .

    因此,要使其发挥作用,您可以将此添加到 包装标签__初始化__ :

    self.setAttribute(QtCore.Qt.WA_StyledBackground)
    self.setStyleSheet('WrappedLabel { padding: 2px; border: 2px solid red; }')