QWidget 在布局分配中变得不可见

QWidget becomes invisible on layout assignment

我正在使用 QGridLayout 进行自定义 window 以放置 window 元素:如标题栏、大小手柄等

当我为我的小部件设置 any 布局时,它不会在开始时显示。 如果我设置 .setVisible(True) 效果很好。

所以问题是:为什么会发生,为什么小部件在布局分配时变得不可见? 这是某种错误还是它被设想出来的?

小部件文件是:

from PySide2 import QtWidgets, QtGui, QtCore


class QCustomWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.background_color = QtGui.QColor(23, 23, 34)

        self._initUI()

    def _initUI(self):
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)

        print(self.isVisible())
        #self.setVisible(True)

        # Is visible without layout
        self.setLayout(QtWidgets.QGridLayout())

        self.layout().setMargin(0)
        self.layout().setSpacing(0)
        # ---------------------------------------

    def showEvent(self, event: QtGui.QShowEvent):
        self.centerOnScreen()

    def paintEvent(self, event: QtGui.QPaintEvent):
        painter = QtGui.QPainter(self)

        painter.setBrush(self.background_color)
        painter.setPen(QtCore.Qt.NoPen)

        painter.drawRect(0, 0, self.width(), self.height())

    def centerOnScreen(self):
        screen = QtWidgets.QDesktopWidget()
        screen_geometry = screen.screenGeometry(self)

        screen_center_x = screen_geometry.center().x()
        screen_center_y = screen_geometry.center().y()

        self.move(screen_center_x - self.width() // 2,
                  screen_center_y - self.height() // 2)

应用程序文件是:

from PySide2 import QtWidgets
from QCustomWindow import QCustomWindow
import sys


app = QtWidgets.QApplication(sys.argv)

window = QCustomWindow()
window.show()

sys.exit(app.exec_())

Qt 除非必要或强制他这样做,否则 Qt 不会更新几何图形,它这样做是出于效率原因。因此,如果未调用 setVisible(True) 或等效方法,则几何图形不会更改。

通过不调用 setVisible(True) 然后在父窗口小部件可见时重新计算大小,此时窗口小部件分析 QSizePolicy、QLayouts 等的信息。在您的特定情况下,具有首选项具有布局,布局根据添加到其中的小部件计算大小,但在您的情况下,它没有添加小部件,因此布局计算的几何形状为 0x0,因此我们看不到它。因此,如果您向 QGridLayout 添加小部件,您将不会看到该问题。

但是如果你调用 setVisible(True) 几何是在那一刻计算的,因为那一刻没有布局,使用 sizeHint,默认为 640x480,因此是可见的。当布局建立时,容器大小等于先前大小和布局提供的大小中的最大值。

总结:

  • 为什么小部件在布局分配中变得不可见?

    如果在小部件中设置了布局,则容器小部件的大小将由分配给布局的小部件确定,在您的情况下,由于有 none,大小为 0x0.

  • 这是某种错误吗?

    不,这不是错误,而是预期的行为。添加小部件或设置大小以显示 window.