3.7 視窗資料傳遞
阿新 • • 發佈:2022-03-23
一、視窗資料傳遞
1.基本概念
1>一個視窗中不同控制元件之間的資料傳遞
2>不同視窗的情況:
- 一種是主視窗獲取子視窗中控制元件的屬性
- 通過訊號與槽機制,一般是子視窗通過發射訊號的形式傳遞資料,主視窗的槽函式獲取這些資料。
2.單一視窗資料傳遞
""" 【簡介】 訊號槽連線滑塊LCD示例 """ import sys from PyQt5.QtWidgets import QWidget, QLCDNumber, QSlider, QVBoxLayout, QApplication from PyQt5.QtCore import Qt class WinForm(QWidget) : def __init__(self) : super().__init__() self.initUI() def initUI(self) : # 1 先建立滑塊和 LCD 部件 lcd = QLCDNumber(self) slider = QSlider(Qt.Horizontal, self) #定義訊號 # 2 通過QVboxLayout來設定佈局 vBox = QVBoxLayout() vBox.addWidget(lcd) vBox.addWidget(slider) self.setLayout(vBox) # 3 valueChanged()是Qslider的一個訊號函式,只要slider的值發生改變,它就會發射一個訊號,然後通過connect連線訊號的接收部件,也就是lcd。 slider.valueChanged.connect(lcd.display) self.setGeometry(300, 300, 350, 150) self.setWindowTitle("訊號與槽:連線滑塊LCD") if __name__ == '__main__' : app = QApplication(sys.argv) form = WinForm() form.show() sys.exit(app.exec_())
演示結果:滑動滑塊,數字發生改變
3.多視窗資料傳遞:呼叫屬性
- 在自定義對話方塊之間通過屬性傳參
點選檢視程式碼
# -*- coding: utf-8 -*- ''' 【簡介】 對話方塊關閉時返回值給主視窗 例子 ''' from PyQt5.Qt import * import sys ''' (1)使用兩個按鈕(Ok和Cancel)分別連線accept()和reject()槽函式。 (2)在類中定義一個靜態函式getDateTime(),該靜態函式返回3個時間值。 原理是利用靜態函式的特性,在靜態函式中例項化 DateDialog類,並呼叫dialog.exec_()函式來顯式執行對話方塊。 通過 dialog.exec_() 的返回值來判斷使用者單擊的是Ok按鈕還是Cancel按鈕,然後做出下一步判斷。 ''' class DateDialog(QDialog) : def __init__(self, parent=None) : super(DateDialog, self).__init__(parent) self.setWindowTitle('DateDialog') # 在佈局中新增部件 layout = QVBoxLayout(self) self.datetime = QDateTimeEdit(self) self.datetime.setCalendarPopup(True) self.datetime.setDateTime(QDateTime.currentDateTime()) layout.addWidget(self.datetime) # 使用兩個button(ok和cancel)分別連線accept()和reject()槽函式 buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) layout.addWidget(buttons) # 從對話方塊中獲取當前日期和時間 def dateTime(self) : return self.datetime.dateTime() # 靜態方法建立對話方塊並返回 (date, time, accepted) @staticmethod def getDateTime(parent=None) : dialog = DateDialog(parent) result = dialog.exec_() date = dialog.dateTime() return (date.date(), date.time(), result == QDialog.Accepted) class WinForm(QWidget): def __init__(self, parent=None): super(WinForm, self).__init__(parent) self.resize(400, 90) self.setWindowTitle('對話方塊關閉時返回值給主視窗例子') self.lineEdit = QLineEdit(self) self.button1 = QPushButton('彈出對話方塊1') self.button1.clicked.connect(self.onButton1Click) self.button2 = QPushButton('彈出對話方塊2') self.button2.clicked.connect(self.onButton2Click) gridLayout = QGridLayout() gridLayout.addWidget(self.lineEdit) gridLayout.addWidget(self.button1) gridLayout.addWidget(self.button2) self.setLayout(gridLayout) ''' 第一種方法:直接在主視窗程式中例項化該對話方塊,然後呼叫該對話方塊的函式來獲取返回值, 根據對 話框的返回值單擊確認按鈕還是取消按鈕來進行下一步操作。 ''' def onButton1Click(self): dialog = DateDialog(self) result = dialog.exec_() date = dialog.dateTime() self.lineEdit.setText(date.date().toString()) print('\n日期對話方塊的返回值') print('date=%s' % str(date.date())) print('time=%s' % str(date.time())) print('result=%s' % result) dialog.destroy() ''' 第二種方法:在主視窗程式中呼叫子視窗的靜態函式,實際上這種方法與第一種方法是一樣的, 只不過它是利用靜態函式的特點,在子視窗的靜態函式中建立例項化物件。 ''' def onButton2Click(self): date, time, result = DateDialog.getDateTime() self.lineEdit.setText(date.toString()) print('\n日期對話方塊的返回值') print('date=%s' % str(date)) print('time=%s' % str(time)) print('result=%s' % result) if result == QDialog.Accepted: print('點選確認按鈕') else: print('點選取消按鈕') if __name__ == "__main__": app = QApplication(sys.argv) form = WinForm() form.show() sys.exit(app.exec_())
4.多視窗資料傳遞:訊號與槽
- 一種是發射PyQt內建的一些訊號;
- 一種是發射自定義的訊號
程式碼:
點選檢視程式碼
# -*- coding: utf-8 -*- from PyQt5.Qt import * import sys class DateDialog(QDialog): Signal_OneParameter = pyqtSignal(str) def __init__(self, parent=None): super(DateDialog, self).__init__(parent) self.setWindowTitle('子視窗:用來發射訊號') # 在佈局中新增部件 layout = QVBoxLayout(self) self.label = QLabel(self) self.label.setText('前者發射內建訊號\n後者發射自定義訊號') self.datetime_inner = QDateTimeEdit(self) self.datetime_inner.setCalendarPopup(True) self.datetime_inner.setDateTime(QDateTime.currentDateTime()) self.datetime_emit = QDateTimeEdit(self) self.datetime_emit.setCalendarPopup(True) self.datetime_emit.setDateTime(QDateTime.currentDateTime()) layout.addWidget(self.label) layout.addWidget(self.datetime_inner) layout.addWidget(self.datetime_emit) # 使用兩個button(ok和cancel)分別連線accept()和reject()槽函式 buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) layout.addWidget(buttons) self.datetime_emit.dateTimeChanged.connect(self.emit_signal) def emit_signal(self): date_str = self.datetime_emit.dateTime().toString() self.Signal_OneParameter.emit(date_str) class WinForm(QWidget): def __init__(self, parent=None): super(WinForm, self).__init__(parent) self.resize(400, 90) self.setWindowTitle('訊號與槽傳遞引數的示例') self.open_btn = QPushButton('獲取時間') self.lineEdit_inner = QLineEdit(self) self.lineEdit_emit = QLineEdit(self) self.open_btn.clicked.connect(self.openDialog) self.lineEdit_inner.setText('接收子視窗內建訊號的時間') self.lineEdit_emit.setText('接收子視窗自定義訊號的時間') grid = QGridLayout() grid.addWidget(self.lineEdit_inner) grid.addWidget(self.lineEdit_emit) grid.addWidget(self.open_btn) self.setLayout(grid) def openDialog(self): dialog = DateDialog(self) '''連線子視窗的內建訊號與主視窗的槽函式''' dialog.datetime_inner.dateTimeChanged.connect(self.deal_inner_slot) '''連線子視窗的自定義訊號與主視窗的槽函式''' dialog.Signal_OneParameter.connect(self.deal_emit_slot) dialog.show() def deal_inner_slot(self, date): self.lineEdit_inner.setText(date.toString()) def deal_emit_slot(self, dateStr): self.lineEdit_emit.setText(dateStr) if __name__ == "__main__": app = QApplication(sys.argv) form = WinForm() form.show() sys.exit(app.exec_())