前言:
今天打算实现自定义子窗口显示信息,之后将参数传递回主窗口。因为只会用QMainWindow创建窗口,又想实现对话框式的效果,网上查了查,发现都是采用QMainWindow和QWidget,而且因为这两个类没有exec()函数,还无法实现阻塞,实现参数回传给主窗口的方法是采用槽。
感觉此类方法还是比较麻烦,需要写相关的函数,所以还是想实现类似QDialog式的效果,点击确认关闭后取回需要传递的参数。经过上午的折腾初步到达想要的效果。大体思路是:将QDialog作为子窗口的父级,利用其exec()函数造成阻塞,改写子窗口的关闭事件,关闭时将父级一起关闭。
参考文献:
1.show()和exec()的区别https://blog.csdn.net/f156207495/article/details/77460527
代码
主窗口打开子窗口的部分:
def on_pb_Package_clicked(self):
mydlg = QDialog(self)
mysub = subWin1(mydlg)
mydlg.setWindowTitle(mysub.windowTitle())
mysub.show()
mydlg.setMaximumSize(0,0)
mydlg.exec()
if mysub.value:
print(mysub.value)
print('结束了')
子窗口类的逻辑扩展(采用QMainWindow):
import sys
import os
from PyQt5 import QtWidgets,QtCore,QtGui
from PyQt5.QtWidgets import QApplication,QMainWindow,QFileDialog
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
from Ui_sub_infoCheck import Ui_MainWindow
class MyMainWin(QMainWindow,Ui_MainWindow):
def __init__(self,parent = None):
super().__init__(parent)#调用父类构造函数,创建窗体
self.setupUi(self)#加载窗体
self.setWindowTitle('子窗口')
self.pb_Yes.setText('确定')
self.pb_No.setText('取消')
self.value = ''
self.myParent = parent
self.closeall = 1
@pyqtSlot()
def on_pb_Yes_clicked(self):
self.value = self.text_Info.toPlainText()
self.close()
@pyqtSlot()
def on_pb_No_clicked(self):
self.value = ''
self.close()
#改写close函数,配合QDialog可实现阻塞效果
def closeEvent(self,e):
if self.closeall:
try:
self.myParent.close()
except:
pass
#########################
if __name__ == '__main__':
app = QApplication(sys.argv)
myWin = MyMainWin()
myWin.show()
sys.exit(app.exec_())
子窗口的UI设计
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(457, 351)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
self.text_Info = QtWidgets.QPlainTextEdit(self.centralwidget)
self.text_Info.setObjectName("text_Info")
self.gridLayout_2.addWidget(self.text_Info, 0, 0, 1, 1)
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setObjectName("widget")
self.gridLayout = QtWidgets.QGridLayout(self.widget)
self.gridLayout.setObjectName("gridLayout")
self.pb_Yes = QtWidgets.QPushButton(self.widget)
self.pb_Yes.setObjectName("pb_Yes")
self.gridLayout.addWidget(self.pb_Yes, 0, 0, 1, 1)
self.pb_No = QtWidgets.QPushButton(self.widget)
self.pb_No.setObjectName("pb_No")
self.gridLayout.addWidget(self.pb_No, 0, 1, 1, 1)
self.gridLayout_2.addWidget(self.widget, 1, 0, 1, 1, QtCore.Qt.AlignHCenter)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "信息确认"))
self.pb_Yes.setText(_translate("MainWindow", "Yes"))
self.pb_No.setText(_translate("MainWindow", "No"))
代码说明:
- 子窗口的代码说明:
self.value = '' self.myParent = parent self.closeall = 1
定义子窗口的返回值,父级、是否关闭父级。
def closeEvent(self,e): if self.closeall: try: self.myParent.close() except: pass
改写子窗口的关闭事件,兼容不关闭父级的情况。
- 主窗口打开子窗口事件的代码说明:
mydlg = QDialog(self) mysub = subWin1(mydlg)
定义一个QDialog,用其作为子窗口的父级建立子窗口。
mysub.show() mydlg.setMaximumSize(0,0) mydlg.exec()
显示子窗口及其父级对话框,通过设置大小达到隐藏对话框。
if mysub.value: print(mysub.value)
阻塞结束后取回子窗口的返回值。