QWidget становится невидимым при назначении макета - PullRequest
1 голос
/ 21 марта 2020

Я создаю собственное окно, используя QGridLayout для размещения элементов окна: например, строки заголовка, размера ручки и т. Д. c.

Когда я устанавливаю 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_())

1 Ответ

2 голосов
/ 21 марта 2020

Qt не обновляет геометрию без необходимости и не заставляет его это делать, и делает это по соображениям эффективности. Так что если setVisible(True) или эквивалентный метод не вызывается, то геометрия не изменится.

Не вызывая setVisible (True), тогда размер пересчитывается, когда родительский виджет виден, и в этот момент виджет анализирует информацию QSizePolicy, QLayouts и др. c. В вашем конкретном случае тот, у которого есть предпочтение, имеет макет, и макет вычисляет размер на основе добавленных к нему виджетов, но в вашем случае у него нет добавленных виджетов, поэтому геометрия, рассчитанная макетом, равна 0x0, что делает его не видимый для нашего взгляда. Поэтому, если вы добавите виджеты в QGridLayout, вы не увидите этой проблемы.

Но если вы вызовете setVisible(True), геометрия вычисляется в этот момент, так как в этот момент нет макета, используется sizeHint , который по умолчанию равен 640x480 и поэтому виден. И когда макет установлен, размер контейнера равен максимуму предыдущего размера и размеру, предоставленному макетом.

Резюме:

  • почему виджет становится невидимым при назначении макета?

    Если в виджете установлен макет, то размер виджета контейнера будет размером, определяемым виджетами, назначенными макету, что в вашем случае , так как их нет, размер равен 0x0.

  • Это какая-то ошибка или она так задумана?

    Нет, это не ошибка, а ожидаемое поведение. Добавьте виджеты или установите размер для отображения окна.

...