我可以将 QMainWindow 添加到堆叠的小部件吗

Posted

技术标签:

【中文标题】我可以将 QMainWindow 添加到堆叠的小部件吗【英文标题】:Can I add QMainWindow to a stacked widget 【发布时间】:2020-11-17 13:11:55 【问题描述】:

我正在尝试使用堆叠的小部件在 MainWindow 和 QDialog Window 之间切换。是否可以在堆叠的小部件中添加 QMainWindow?

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(400, 300)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(180, 110, 47, 13))
        self.label.setObjectName("label")
        self.nextButt = QtWidgets.QPushButton(self.centralwidget)
        self.nextButt.setGeometry(QtCore.QRect(10, 270, 75, 23))
        self.nextButt.setObjectName("nextButt")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "Hi"))
        self.nextButt.setText(_translate("MainWindow", "Next"))


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(400, 300)
        self.menuButt = QtWidgets.QPushButton(Dialog)
        self.menuButt.setGeometry(QtCore.QRect(20, 250, 75, 23))
        self.menuButt.setObjectName("menuButt")

        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(200, 100, 47, 13))
        self.label.setObjectName("label")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.menuButt.setText(_translate("Dialog", "Menu"))
        self.label.setText(_translate("Dialog", "Bye"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    main_win = Ui_MainWindow()
    dialog = Ui_Dialog()
    stackedWidget = QStackedWidget()
    stackedWidget.addWidget(main_win)
    stackedWidget.addWidget(dialog)
    stackedWidget.show()
    sys.exit(app.exec_())

但我不断收到错误 TypeError: addWidget(self, QWidget): argument 1 has unexpected type 'Ui_MainWindow'

【问题讨论】:

【参考方案1】:

问题在于您正在尝试添加所谓的表单类。这是一个标准的 python object 类型,它在 PyQt 上用作抽象对象“助手”,能够在现有的空 QWidget 子类上构建 UI。

QStackedWidget 期望的是 QWidget 子类(QMainWindow、QDialog 等)。不幸的是,当您创建 QMainWindow 实例时,您从未将它与 Ui_MainWindow.setupUi() 函数一起使用,甚至没有创建 QDialog 实例。

这是您的代码的修订版本:

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)

    mainWindow = QtWidgets.QMainWindow()
    mainWindowUi = Ui_MainWindow()
    mainWindowUi.setupUi(mainWindow)
    dialog = QtWidgets.QDialog()
    dialogUi = Ui_Dialog()
    dialogUi.setupUi(dialog)

    stackedWidget = QtWidgets.QStackedWidget()
    stackedWidget.addWidget(mainWindow)
    stackedWidget.addWidget(dialog)

    mainWindowUi.nextButt.clicked.connect(
        lambda: stackedWidget.setCurrentWidget(dialog))
    dialogUi.menuButt.clicked.connect(
        lambda: stackedWidget.setCurrentWidget(mainWindow))
    stackedWidget.show()
    sys.exit(app.exec_())

一些注意事项:

请记住,pyuic 生成的文件应该永远被修改(也不应该试图模仿他们的行为);为了简单起见,我可以假设您已经加入了他们的代码,但如果您没有加入他们的代码,而这实际上就是您尝试实现程序的方式,您必须重新考虑它:pyuic 生成的文件应该永远被修改(并且它们的代码不应添加到您的脚本中),因为它们应始终用作导入;阅读更多关于 using Designer 的信息; QMainWindow 是一种非常特殊的 QWidget 子类,应该始终用作 *** 窗口,而不是嵌入到另一个小部件中;如果要添加子小部件,请使用标准 QWidget(Designer 启动对话框中的“Widget”,通常称为“表单”); 使用上面的代码,您可能会得到一个无法使用的界面,因为除非调整***窗口的大小,否则两个子窗口小部件的内容将不可见;始终不鼓励使用固定的几何图形(位置和大小),因为这会导致小部件无法访问或重叠,应始终首选 layout managers;

【讨论】:

以上是关于我可以将 QMainWindow 添加到堆叠的小部件吗的主要内容,如果未能解决你的问题,请参考以下文章

将自定义小部件添加到 QStackedWidget

如何将菜单添加到从 Qwidget 派生的小部件

有没有办法将自定义 QGroupBox 添加到任何小部件/布局?

如何正确地将一个小部件堆叠到另一个上?

QMainWindow和QWidget

如何在 Qt 中将动画用于堆叠的小部件?