QWidget::setLayout:试图在已经有布局的 MainWindow 上设置 QLayout ""。

28

我正在使用PyQt4制作一个应用程序,这是我的目前的代码:

import sys
from PyQt4 import QtGui, QtCore

class MainWindow(QtGui.QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.initUi()

    def initUi(self):
        self.setWindowTitle('Main Menu')
        self.setFixedSize(1200, 625)
        self.firstWidgets()
        self.show()

    def firstWidgets(self):
        self.vbox1 = QtGui.QVBoxLayout()
        self.task1 = QtGui.QLabel('Check 1', self)
        self.task1CB = QtGui.QCheckBox(self)
        self.hbox1 = QtGui.QHBoxLayout()
        self.hbox1.addWidget(self.task1)
        self.hbox1.addWidget(self.task1CB)
        self.vbox1.addLayout(self.hbox1)

        self.setLayout(self.vbox1)


def main():
    application = QtGui.QApplication(sys.argv)
    gui = MainWindow()
    sys.exit(application.exec_())

if __name__=='__main__':
    main()

我的问题出现在 MainWindow.firstWidgets() 中。我尝试设置一个布局,但是我得到了一个错误,尽管这是我第一次为该表单使用 .setLayout,这让我感到困惑。

QWidget::setLayout: 试图在 MainWindow 上设置 QLayout "",但其已经拥有一个布局。

3个回答

61

你无法直接在QMainWindow上设置QLayout。你需要创建一个QWidget,将其设置为QMainWindow中央窗口部件,并将QLayout分配给该窗口部件。

wid = QtGui.QWidget(self)
self.setCentralWidget(wid)
layout = QtGui.QVBoxLayout()
wid.setLayout(layout)

注意: 这是针对Qt4的代码 -- 请查看此问题的其他答案以获取Qt5更新的代码。


这与我的MainWindow类继承QMainWindow而不是QtGui.QWidget有关吗?似乎唯一的方法是继承QtGui.MainWindow才能在QMainWindow内部获取menuBar。 - WewLad
是的,你可能想要继承自QMainWindow,因为它是唯一一个看起来和功能像应用程序窗口的类。但它不接受布局。 - Brendan Abel

15

仅对Brenden Abel的答案进行更新:

现在QWidget和QVBoxLayout(对于Python3,PyQt5)包含在PyQt5.QtWidgets模块中,而不是PyQt5.QtGui模块。

因此,更新的代码:

wid = QtWidgets.QWidget(self)
self.setCentralWidget(wid)
layout = QtWidgets.QVBoxLayout()
wid.setLayout(layout)

4

这是一个使用PyQt5的示例

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QWidget


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('My App')
        
        # Cannot set QxxLayout directly on the QMainWindow
        # Need to create a QWidget and set it as the central widget
        widget = QWidget()
        layout = QVBoxLayout()
        b1 = QPushButton('Red'   ); b1.setStyleSheet("background-color: red;")
        b2 = QPushButton('Blue'  ); b2.setStyleSheet("background-color: blue;")
        b3 = QPushButton('Yellow'); b3.setStyleSheet("background-color: yellow;")
        layout.addWidget(b1)
        layout.addWidget(b2)
        layout.addWidget(b3)
            
        widget.setLayout(layout)
        self.setCentralWidget(widget)


def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

迄今为止最清晰的解释。这正是我寻找已经几天了的评论所说的。 - Marcin
也适用于C++,谢谢! widget = new QWidget; layout = new QGridLayout; widget->setLayout(layout); setCentralWidget(widget); - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接