当我在PyQt6中使用自定义Widget作为QMainWindow的CentralWidget时,CentralWidget和QMainWindow之间存在间隙

问题描述 投票:0回答:1

当我在PyQt6中使用自定义Widget作为QMainWindow的CentralWidget时,CentralWidget和QMainWindow之间存在间隙?我想知道为什么会这样。这是我的代码:

from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QLabel, QHBoxLayout
import sys


class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self._layout = QHBoxLayout(self)
        self.label = QLabel("hello")
        self.label.setStyleSheet("QLabel {color: white;}")
        self._layout.addWidget(self.label)
        self.setStyleSheet("background-color: black; color: white;")


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # When using custom widgets, there is a gap
        self.central_widget = MyWidget()

        # When using Qwidget, there is no gap
        # self.central_widget = QWidget()
        # self.central_layout = QHBoxLayout()
        # self.central_layout.addWidget(QLabel("hello"))
        # self.central_widget.setLayout(self.central_layout)

        self.setCentralWidget(self.central_widget)
        # self.central_widget.setStyleSheet("background-color: black; color: white; border: none;")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec())

picture 1

picture 2

我想知道为什么使用自定义小部件和使用 QWidget 之间存在差异,以及如何修复它。

python pyqt pyqt6 qmainwindow
1个回答
0
投票

您误解了结果。

在您的自定义子类中,您将设置以下样式表:

background-color: black; color: white;

这会产生以下结果:

  1. 子类 QWidget 绘制样式表中设置的背景(请参阅有关 QWidget 的 QSS 文档),唯一的例外是顶级小部件(窗口);
  2. 使用通用属性(没有适当的选择器类型)将自动将这些属性传播到任何子小部件;

您看到的不是小部件的背景,而是标签的背景。您在边缘附近看到的间隙是 layout 边距。

如果在标签上指定对齐方式,情况会更清楚;将子项添加到布局时,布局将尝试使小部件占据“布局单元格”内尽可能多的可用空间,但如果指定了对齐方式,它将仅使用小部件的大小提示。
尝试执行以下操作:

self._layout.addWidget(self.label, alignment=Qt.AlignCenter)

你会看到这个:

理论上,你可以尝试取消布局边距:

self._layout.setContentsMargins(0, 0, 0, 0)

实际上,这不是正确的解决方案,因为:

  • 您可能仍然需要布局边距;
  • 布局中的间距不会有背景,因为它只显示在子级上,而不是父级上;
  • 如果您需要像上面那样指定布局对齐方式,您仍然会有未绘制的间隙;
  • 您仍然会遇到其他小部件的问题(由于使用通用 QSS 属性,家长应该始终避免);

因此,为了使小部件拥有自己的背景,您必须在 QSS 中使用正确的语法(使用选择器类型)并确保父小部件实际绘制其背景,这可以通过设置

Qt.WA_StyledBackground
来实现属性,或者通过实现
paintEvent()
.

class MyWidget(QWidget):
    def __init__(self):
        ...
        self.setStyleSheet("MyWidget { background-color: black;} ")
        self.setAttribute(Qt.WA_StyledBackground)

或者:

class MyWidget(QWidget):
    def __init__(self):
        ...
        self.setStyleSheet("MyWidget { background-color: black;} ")

    def paintEvent(self, event):
        qp = QStylePainter(self)
        opt = QStyleOption()
        opt.initFrom(self)
        qp.drawPrimitive(QStyle.PE_Widget, opt)
© www.soinside.com 2019 - 2024. All rights reserved.