PyQt5显示关闭的子窗口

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

我正在尝试通过X按钮将其关闭后显示子窗口。我用Qt设计器制作了图形。

main.py

# -*- coding: utf-8 -*-
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(402, 332)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.mdiArea = QtWidgets.QMdiArea(self.centralwidget)
        self.mdiArea.setGeometry(QtCore.QRect(-1, -1, 401, 291))
        self.mdiArea.setObjectName("mdiArea")
        self.subwindow = QtWidgets.QWidget()
        self.subwindow.setObjectName("subwindow")
        self.pushButton = QtWidgets.QPushButton(self.subwindow)
        self.pushButton.setGeometry(QtCore.QRect(0, 0, 75, 23))
        self.pushButton.setObjectName("pushButton")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 402, 21))
        self.menubar.setObjectName("menubar")
        self.menuStart = QtWidgets.QMenu(self.menubar)
        self.menuStart.setObjectName("menuStart")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionOpenSubWin = QtWidgets.QAction(MainWindow)
        self.actionOpenSubWin.setObjectName("actionOpenSubWin")
        self.menuStart.addAction(self.actionOpenSubWin)
        self.menubar.addAction(self.menuStart.menuAction())

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.subwindow.setWindowTitle(_translate("MainWindow", "Subventana"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.menuStart.setTitle(_translate("MainWindow", "Start"))
        self.actionOpenSubWin.setText(_translate("MainWindow", "OpenSubWin"))

以及用于创建应用程序的代码。

gestor.py

import sys
import os

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

from resources.main import *

class myMainClass(QtWidgets.QMainWindow, ):
    def __init__(self, parent=None):
        super(myMainClass, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.mdiArea.addSubWindow(self.ui.subwindow)
        #conection
        self.ui.actionOpenSubWin.triggered.connect(self.showSubWin)

    def showSubWin(self):
        self.ui.subwindow.show()

if __name__ == "__main__":
    print('start')
    app = QApplication([])
    myapp = myMainClass()
    myapp.show()
    sys.exit(app.exec_())

所以,它打开得很好,但是如果Y关闭子窗口,则调用self.ui.subwindow.show()会崩溃。

我正在尝试将子窗口放入变量中,然后再次创建,它不会崩溃,但是会打开一个没有内部按钮的窗口。

class myMainClass(QtWidgets.QMainWindow, ):
    def __init__(self, parent=None):
        super(myMainClass, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)


        self.sw=QtWidgets.QMdiSubWindow()
        self.sw.setWidget(self.ui.subwindow)
        self.ui.mdiArea.addSubWindow(self.sw)
        #conection
        self.ui.actionOpenSubWin.triggered.connect(self.showSubWin)

    def showSubWin(self):
        self.sw.setWidget(self.ui.subwindow)
        self.sw.show()

我很确定我误解了Pyqt的管理方式。

python-3.x pyqt5 mdi
1个回答
0
投票

您的第二次尝试(使用变量sw)是正确的方法。尽管您可以简化3行,但是只需保留addSubWindow的返回值即可:

self.sw = self.ui.mdiArea.addSubWindow(self.ui.subwindow)

然后您需要为sw禁用“关闭时删除”标志:

self.sw.setAttribute(QtCore.Qt.WA_DeleteOnClose, False)

doc of QWidget.close提到此标志:

[首先,它向小部件发送PySide.QtGui.QCloseEvent。如果小部件接受关闭事件,则为hidden。如果该小部件具有Qt.WA_DeleteOnClose标志,则该小部件也将被删除。

[微妙的地方是将此标志设置在self.sw(QMdiSubWindow)上,而不是在self.ui.subwindow上(在self.sw删除后,内部小部件的关闭事件为时已晚)。

© www.soinside.com 2019 - 2024. All rights reserved.