多窗口數據傳輸一般通過子窗口發射信號,主窗口通過槽函數獲取信號,然后獲取信號中的數據;
可以認為有兩種方式來實現多窗口數據傳遞:
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_())