我正在尝试通过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的管理方式。
您的第二次尝试(使用变量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
删除后,内部小部件的关闭事件为时已晚)。