PyQt5-多窗口数据传输
多窗口数据传输一般通过子窗口发射信号,主窗口通过槽函数获取信号,然后获取信号中的数据;
可以认为有两种方式来实现多窗口数据传递:
1、通过对话框之间的属性传参实现
则是通过定义子窗口对象,在子窗口类中定义静态方法该方法在对话框执行完毕后即自动调用了exec_()方法,此时返回值作为了返回传递给父窗口的数据;
父窗口中,调用该静态方法来直接打开子窗口,获取返回值,拿到数据;
或者子窗口不定义静态方法,在父窗口中直接实例化子窗口对象,获取到exec_()方法返回值,直接调用子窗口对象属性获取要的数据即可;
例如:
1 #窗口之间数据传递(通过属性来进行消息传递) 2 from PyQt5.QtWidgets import QDialogButtonBox, QDateTimeEdit,QDialog,QComboBox,QTableView,QAbstractItemView,QHeaderView,QTableWidget, QTableWidgetItem, QMessageBox,QListWidget,QListWidgetItem, QStatusBar, QMenuBar,QMenu,QAction,QLineEdit,QStyle,QFormLayout, QVBoxLayout,QWidget,QApplication ,QHBoxLayout, QPushButton,QMainWindow,QGridLayout,QLabel 3 from PyQt5.QtGui import QIcon,QPixmap,QStandardItem,QStandardItemModel,QCursor,QFont,QBrush,QColor,QPainter,QMouseEvent,QImage,QTransform 4 from PyQt5.QtCore import QStringListModel,QAbstractListModel,QModelIndex,QSize,Qt,QObject,pyqtSignal,QTimer,QEvent,QDateTime,QDate 5 6 import sys 7 class Win(QWidget): 8 def __init__(self,parent=None): 9 super(Win, self).__init__(parent) 10 self.resize(400,400) 11 12 self.btn=QPushButton("按钮",self) 13 self.btn.move(50,50) 14 self.btn.setMinimumWidth(80) 15 16 #显示子窗口传来的日期字符串或者其他数据 17 self.label=QLabel('显示信息',self) 18 self.label.setMinimumWidth(420) 19 20 self.btn.clicked.connect(self.fn) 21 def fn(self): 22 date,time,res= Dialog.getResult(self) 23 print(date,time,res) 24 #或者下面写法,上面使用了下面定义的静态方法,下面则直接实例化自定义的对话框类 25 # dialog=Dialog() 26 # res=dialog.exec_() 27 # date=dialog.datetime.date() 28 # time=dialog.datetime.time() 29 # print(res,date,time) 30 31 #弹出框对象 32 class Dialog(QDialog): 33 34 def __init__(self,parent=None): 35 super(Dialog, self).__init__(parent) 36 layout=QVBoxLayout(self) 37 self.label=QLabel(self) 38 self.datetime=QDateTimeEdit(self) 39 self.datetime.setCalendarPopup(True) 40 self.datetime.setDateTime(QDateTime.currentDateTime()) 41 self.label.setText("请选择日期") 42 layout.addWidget(self.label) 43 layout.addWidget(self.datetime) 44 45 buttons=QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel,Qt.Horizontal,self) 46 buttons.accepted.connect(self.accept)#点击ok,隐士存在该方法 47 buttons.rejected.connect(self.reject)#点击cancel,该方法默认隐士存在 48 layout.addWidget(buttons) 49
#该方法在父类方法中调用,直接打开了子窗体,返回值则用于向父窗体数据的传递 50 @staticmethod 51 def getResult(self,parent=None): 52 dialog=Dialog(parent) 53 result=dialog.exec_() 54 d=dialog.datetime.dateTime() 55 return (d.date(),d.time(),result) 56 57 if __name__=='__main__': 58 59 app=QApplication(sys.argv) 60 win = Win() 61 win.show() 62 sys.exit(app.exec_())
2、窗口之间使用信号和槽机制传参
例如(窗口之间使用信号和槽进行数据传递):定义一个Dialog子窗口类, 一个主窗口Win类;
子窗口类中定义:
自定义的信号:
dialogSignel=pyqtSignal(int ,str)
组件:
Qlabel提示信息:请选择日期;
QDialogButtonBox按钮:一组带有确定和取消的按钮组件
QDateEdit日期组件;
方法:
accept和reject,前者点击确定后者点击取消时执行的槽函数
子窗口操作:
确定按钮默认消息accepted,连接槽函数accept, accept来发送消息:
取消按钮默认消息rejected,连接槽函数reject,reject发送消息:
部分代码:
1 def accept(self):#点击ok是发送内置信号 2 print("accept") 3 self.dialogSignel.emit(0,self.datetime.text()) 4 self.destroy() 5 def reject(self):#点击cancel时,发送自定义信号 6 print('reject') 7 self.dialogSignel.emit(1,"清空") 8 self.destroy()
父窗口类定义:
组件:QLabel 用于显示获取子窗口的日期
QPushButton点击该按钮则显示子窗体
方法:自定义openDialog方法,打开子窗体;
槽函数:slot_inner,slot_emit,前者处理内置消息,后者处理自定义消息
openDialog方法做这几件事情:
第一:日期控件对象的内置消息dateChanged,连接槽函数slot_inner,slot_inner方法来获取默认消息参数日期数据,并修改当前父窗口中QLabel组件新信息;
第二:子窗体的自定义消息dialogSignel属性,连接槽函数slot_emit,slot_emit方法获取dialogSignel消息中的参数信息,并修改当前父窗口QLabel组件新消息;
完成代码如下:
1 #窗口之间数据传递(通过属性方式) 2 from PyQt5.QtWidgets import QDialogButtonBox, QDateTimeEdit,QDialog,QComboBox,QTableView,QAbstractItemView,QHeaderView,QTableWidget, QTableWidgetItem, QMessageBox,QListWidget,QListWidgetItem, QStatusBar, QMenuBar,QMenu,QAction,QLineEdit,QStyle,QFormLayout, QVBoxLayout,QWidget,QApplication ,QHBoxLayout, QPushButton,QMainWindow,QGridLayout,QLabel 3 from PyQt5.QtGui import QIcon,QPixmap,QStandardItem,QStandardItemModel,QCursor,QFont,QBrush,QColor,QPainter,QMouseEvent,QImage,QTransform 4 from PyQt5.QtCore import QStringListModel,QAbstractListModel,QModelIndex,QSize,Qt,QObject,pyqtSignal,QTimer,QEvent,QDateTime,QDate 5 6 import sys 7 class Win(QWidget): 8 def __init__(self,parent=None): 9 super(Win, self).__init__(parent) 10 self.resize(400,400) 11 12 self.btn=QPushButton("按钮",self) 13 self.btn.move(50,50) 14 self.btn.setMinimumWidth(120) 15 self.btn.clicked.connect(self.openDialog) 16 17 #显示子窗口传来的日期字符串或者其他数据 18 self.label=QLabel('这里显示信息',self) 19 self.label.setMinimumWidth(420) 20 21 #打开Dialog 22 def openDialog(self): 23 dialog=Dialog(self) 24 #连接【子窗口内置消息和主窗口的槽函数】 25 dialog.datetime.dateChanged.connect(self.slot_inner) 26 #连接【子窗口自定义消息和主窗口槽函数】 27 dialog.dialogSignel.connect(self.slot_emit) 28 dialog.show() 29 30 def slot_inner(self,date): 31 print("主窗口:method_1") 32 self.label.setText("①"+str(date)+">>内置消息获取日期为") 33 34 35 def slot_emit(self,flag,str): 36 print("主窗口:method_2") 37 print(flag) 38 if flag=="0":#点击ok 39 self.label.setText("②"+str(str)+">>自定义消息") 40 else:#点击cancel 41 self.label.setText(str) 42 43 #弹出框对象 44 class Dialog(QDialog): 45 #自定义消息 46 dialogSignel=pyqtSignal(int,str) 47 48 def __init__(self,parent=None): 49 super(Dialog, self).__init__(parent) 50 layout=QVBoxLayout(self) 51 self.label=QLabel(self) 52 self.datetime=QDateTimeEdit(self) 53 self.datetime.setCalendarPopup(True) 54 self.datetime.setDateTime(QDateTime.currentDateTime()) 55 self.label.setText("请选择日期") 56 layout.addWidget(self.label) 57 layout.addWidget(self.datetime) 58 59 buttons=QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel,Qt.Horizontal,self) 60 buttons.accepted.connect(self.accept)#点击ok 61 buttons.rejected.connect(self.reject)#点击cancel 62 layout.addWidget(buttons) 63 def accept(self):#点击ok是发送内置信号 64 print("accept") 65 self.dialogSignel.emit(0,self.datetime.text()) 66 self.destroy() 67 def reject(self):#点击cancel时,发送自定义信号 68 print('reject') 69 self.dialogSignel.emit(1,"清空") 70 self.destroy() 71 72 73 if __name__=='__main__': 74 75 app=QApplication(sys.argv) 76 win = Win() 77 win.show() 78 sys.exit(app.exec_())