Python深度學習實戰(zhàn)PyQt5信號與槽的連接
1. 信號與槽(Signals and slots)
信號與槽機制是 PyQt 的核心機制,用于對象之間的通信,也就是實現(xiàn)函數(shù)之間的自動調用。
1.1 信號與槽的原理
簡單地說,將信號與槽函數(shù)連接后,當信號被觸發(fā)時,槽函數(shù)將被自動調用。
分析這個過程,涉及到幾個基本概念和關系:
- 信號:信號可以是一個動作,也可以是對象的一種狀態(tài),用于觸發(fā)所連接的槽。
- 槽:槽就是一個函數(shù),可以由連接的信號觸發(fā)。
- 發(fā)射信號:信號被發(fā)射時,自動調用信號連接的槽函數(shù)。通常,在對象的狀態(tài)改變時發(fā)射信號。
- 信號可以帶有參數(shù),但必須與槽函數(shù)的參數(shù)相對應。
- 一個信號可以連接多個槽函數(shù),多個信號也可以連接到一個槽函數(shù)。
- 一個信號可以連接到另一個信號上。
- 很多窗口部件(控件)內置了一下信號和槽,可以直接調用。也可以按需求自定義信號和槽。
1.2 信號發(fā)送者與槽的接收者
信號的發(fā)送者通常是一個控件對象,在控件對象的狀態(tài)發(fā)生變化時發(fā)送信號。常見的發(fā)送者是圖形窗口中的各種控件對象,但也可以是動作對象。
槽的接收者通常也是控件對象。槽函數(shù)是一個自定義的槽函數(shù),或控件內置的槽函數(shù)。一般地,槽函數(shù)也有一個對象作為主體,即對于接受者這個控件對象執(zhí)行函數(shù)定義的操作。例如槽函數(shù)執(zhí)行的功能是關閉,哪么究竟是關閉那個控件呢?關閉對象就是接受者。
為了方便講解信號與槽的連接,我們用 QtDesigner 在上節(jié)設計的圖形窗口 uiDemo3.ui 的基礎上,增加幾個按鈕對象和文本行編輯對象:
打開 PyCharm,從 Tools -> ExternalTools -> QtDesigner 打開 QtDesigner,打開 uiDemo3.ui 文件。
鼠標點擊選中 QtDesigner 左側控件欄 Buttons 中的 PushButton,按住鼠標不放,將其拖動到中間的圖形界面后松開鼠標,就在圖形界面中創(chuàng)建了一個 PushButton 控件。
鼠標點擊選中 QtDesigner 左側控件欄 InputWidget 中的 LineEdit,按住鼠標不放,將其拖動到中間的圖形界面后松開鼠標,就在圖形界面中創(chuàng)建了一個 LineEdit 控件。
重復以上步驟,再建立幾個 PushButton 控件和 LineEdit 控件。
- 注意在 QtDesigner 右側 “對象查看器” 中所顯示的控件名稱和屬性,多個 PushButton、LineEdit 被自動賦予不同的命名(objectName),如:LineEdit_1、LineEdit_2、LineEdit_3,這就如同桌子有幾個抽屜分別標記為 “抽屜1”、“抽屜2”、“抽屜3” 以便識別。
- 控件的名稱和其它屬性都可以在 “屬性編輯器” 中編輯修改。
鼠標選中在圖形界面中創(chuàng)建的 PushButton 控件或 LineEdit 控件,可以拖動控件調整位置。
鼠標雙擊 PushButton 按鈕,可以編輯按鈕控件的標簽即按鈕上的顯示內容。
為了便于講解,本例將各 PushButton 控件的顯示內容(text 屬性)修改為:“1# 按鈕” ~ “4# 按鈕”,將各 LineEdit 控件的顯示內容(text 屬性)修改為:“文本編輯行-1” ~ “文本編輯行-3”。
將這個應用程序圖形界面另存為 uiDemo4.ui,其預覽效果如下:
2. QtDesigner 建立信號與槽的連接
2.1 信號與槽的連接:不同的發(fā)送者與接收者,槽函數(shù)為控件的內置函數(shù)
QtDesigner 提供了便捷和直觀的信號/槽編輯方法。
本例介紹不同的發(fā)送者與接收者,槽函數(shù)為控件的內置函數(shù)的操作方法。不同類型的控件分別內置了若干方法,例如 QPushButton 控件內置的方法包括:點擊、選中、狀態(tài)變化、顯示菜單等,而 QLineEdit 控件內置的方法包括:清空、復制、剪切、粘貼、全選、撤銷操作等。使用控件內置的方法作為槽函數(shù),可以直接調用,不需要對函數(shù)進行定義。
我們所設計的功能是:當點擊按鈕控件 “pushButton_1” 時,清空文本編輯控件 “l(fā)ineEdit_1” 的顯示內容。注意我們稱按鈕控件為 “l(fā)ineEdit_1” 而不是 “文本編輯行-1”,這是因為 lineEdit_1 才是控件名稱,在程序中是不變的,而 “文本編輯行-1” 只是顯示內容,可以在程序中修改。
QtDesigner 設置信號/槽的連接的操作步驟如下:
(1)選擇菜單項 “Edit” -> 編輯信號/槽,或者通過快捷鍵 F4 或在工具欄選擇,進入信號/槽編輯模式。
(2)選中控件對象發(fā)送者,此處為按鈕控件 “pushButton_1”,鼠標左鍵長按不放,該按鈕控件變?yōu)闇\紅色。
- 鼠標左鍵繼續(xù)長按不放,并移動鼠標,當鼠標移出控件對象區(qū)域后,出現(xiàn)一條帶箭頭的紅線和一個紅色的接地符號。
- 鼠標左鍵繼續(xù)長按不放,并拖動鼠標到控件對象 “l(fā)ineEdit_1”,松開鼠標左鍵,就建立了以控件對象 “pushButton_1” 為發(fā)送者、控件對象 “l(fā)ineEdit_1” 為接收者的信號/槽連接。
- 此時控件對象 “pushButton_1” 和 “l(fā)ineEdit_1” 都變?yōu)闇\紅色,帶箭頭的紅線從 “pushButton_1” 出發(fā),指向 “l(fā)ineEdit_1” 結束。
(3)同時彈出對話框 “配置連接 - QtDesigner”,對話框的左側顯示發(fā)送者控件的信號選項,對話框的右側顯示接收者的控件選項。
- 根據(jù)功能要求,觸發(fā)信號為按鈕 “pushButton_1” 被點擊,從對話框左側選中 “clicked()”;
- 根據(jù)功能要求,收到信號后動作是清空文本編輯控件 “l(fā)ineEdit_1”,從對話框右側選中 “clear()”;
- 點擊對話框下方的按鈕 “OK”,完成該信號/槽連接的配置。
2.2 信號與槽的連接:不同的發(fā)送者與接收者,槽函數(shù)為自定義函數(shù)
本例介紹不同的發(fā)送者與接收者,槽函數(shù)為自定義函數(shù)的操作方法。
在 2.1 中介紹了使用控件內置的方法作為槽函數(shù),可以直接調用,不需要對函數(shù)進行定義。程序設計中的核心功能通常是程序員根據(jù)需求開發(fā)的自定義函數(shù)。使用自定義函數(shù)作為槽函數(shù),一方面當然是要編寫自定義函數(shù),另一方面要將自定義函數(shù)添加到槽函數(shù)配置連接表中。
我們所設計的功能是:
當點擊按鈕控件 “pushButton_2” 時,清空文本編輯控件 “l(fā)ineEdit_2” 的顯示內容,并顯示文本信息 “current signal: click pushButton_2”。
在主程序中要編寫一個自定義函數(shù)實現(xiàn)該功能,將該自定義函數(shù)命名為 click_pushButton_2()。
注意我們編寫的自定義函數(shù) click_pushButton_2(),雖然功能只是對文本編輯控件 “l(fā)ineEdit_2” 進行操作,但對于自定義函數(shù)也可以完成任意的其它功能,對其它控件按照控件名稱進行操作。因此該槽函數(shù)的接收者并不是文本編輯控件 “l(fā)ineEdit_2”,而是主窗口控件 “MainWindow”。
QtDesigner 設置信號/槽的連接的操作步驟如下:
首先要在 QtDesigner 將自定義函數(shù)添加到槽函數(shù)配置連接表中——非常重要。
網(wǎng)上的很多文章都沒有講具體實現(xiàn)方法,這個操作的入口也很難找到。
(1)在 QtDesigner 右側上方的 “對象查看器”,選中 MainWindow 或其它頂層對象,單擊鼠標右鍵喚出下拉菜單,選擇 “改變信號/槽”;
- 彈出 “MainWindow 的信號/槽” 對話框,對話框的上方顯示槽的選項,下方顯示信號選項。
- 點擊對話框上方 “槽” 選項框下部的綠色 “+”,系統(tǒng)在 “槽” 選項表的最后自動增加了一行 “slot1()”。這就是新增的自定義槽函數(shù)。
- 點擊選中 “slot1()”,再鼠標雙擊,就可以修改槽函數(shù)的函數(shù)名,例如修改為 click_pushButton_2()。
- 再點擊對話框上方 “槽” 選項框下部的綠色 “+”,可以繼續(xù)逐一添加自定義的槽函數(shù)。
然后設置信號/槽的連接:
(2)選擇菜單項 “Edit” -> 編輯信號/槽,或者通過快捷鍵 F4 或在工具欄選擇,進入信號/槽編輯模式。
- 選中控件對象發(fā)送者,此處為按鈕控件 “pushButton_2”,長按鼠標左鍵并移動,當鼠標移出控件對象區(qū)域后,出現(xiàn)一條帶箭頭的紅線和一個紅色的接地符號。
- 松開鼠標左鍵,就建立了以控件對象 “pushButton_2” 為發(fā)送者、控件對象 “MainWindow” 為接收者的信號/槽連接。此時控件對象 “pushButton_2” 變?yōu)闇\紅色,帶箭頭的紅線從 “pushButton_2” 出發(fā),并不指向其它控件,而是以一個接地符號結束。
(3)同時彈出對話框 “配置連接 - QtDesigner”,對話框的左側顯示發(fā)送者控件 “pushButton_2” 的信號選項,對話框的右側顯示接收者 “MainWindow” 的控件選項。
- 根據(jù)功能要求,觸發(fā)信號為按鈕 “pushButton_2” 被點擊,從對話框左側選中 “clicked()”;
- 對話框右側接收者 “MainWindow” 的控件選項列表中,顯示了剛才添加的幾個自定義函數(shù),選擇 “click_pushButton_2()”;
- 點擊對話框下方的按鈕 “OK”,完成該信號/槽連接的配置。
最后,別忘了要在主程序中編寫自定義的函數(shù)。但這已不屬于 QtDesigner 設計的內容了,在此不再詳述。
類似地,我們設計:當點擊按鈕控件 “pushButton_3” 時,在文本編輯控件 "lineEdit_1"顯示當前系統(tǒng)日期,在文本編輯控件 "lineEdit_2"顯示當前系統(tǒng)時間,在文本編輯控件 “l(fā)ineEdit_3” 顯示提示信息。在主程序中編寫一個自定義函數(shù) click_pushButton_3(),并與 “pushButton_3” 建立信號/槽連接。
這表明:在自定義的子函數(shù)中,可以同時操作多個控件對象,進而可以實現(xiàn)用戶定義的各種功能。
2.3 信號與槽的連接:相同的發(fā)送者與接收者,槽函數(shù)為控件的內置函數(shù)
本例介紹相同的發(fā)送者與接收者,槽函數(shù)為控件的內置函數(shù)的操作方法。
顧名思義,相同的發(fā)送者與接收者,就是說信號的發(fā)送者與槽函數(shù)的接收者是同一個控件對象。這是什么情況?例如,一個開關按鈕有 “On/Off” 兩種狀態(tài),每按一次則按鈕狀態(tài)發(fā)生翻轉。類似地,選項框也有選中、未選中兩種狀態(tài)。特殊地,點擊按鈕后,關閉該按鈕控件,也屬于相同的發(fā)送者與接收者。
我們首先將控件對象 “pushButton_4” 從按鈕控件 QPushButton 改變?yōu)?選項框控件 “QCheckBox”:
- 點擊控件對象 “pushButton_4”,控件對象的周圍邊界顯示幾個藍色小方塊;
- 點擊鼠標右鍵喚出下拉菜單,選擇:“變型為” ->“QCheckBox”。
此時,設計界面窗口中的按鈕控件,變成了一個選項框。同時,右側 “對象查看器” 中的控件 “pushButton_4”,也自動變更為 “checkBox_4”。變更的控件 “checkBox_4” 繼承了原來控件 “pushButton_4” 的一些屬性,如:位置、尺寸、顯示內容。
接下來設置信號/槽的連接:
(1)選擇菜單項 “Edit” -> 編輯信號/槽,或者通過快捷鍵 F4 或在工具欄選擇,進入信號/槽編輯模式。
(2)選中控件對象發(fā)送者,此處為按鈕控件 “checkBox_4”,長按鼠標左鍵并移動,當鼠標移出控件對象區(qū)域后,出現(xiàn)一條帶箭頭的紅線和一個紅色的接地符號。
- 長按鼠標左鍵,拖動鼠標再回到控件對象 “checkBox_4” 區(qū)域后松開鼠標左鍵,就建立了發(fā)送者和接收者都是控件對象 “checkBox_4” 的信號/槽連接。
- 此時控件對象 “checkBox_4” 變?yōu)闇\紅色,帶箭頭的紅線從 “checkBox_4” 出發(fā),又返回到 “checkBox_4” 結束。
(3)同時彈出了對話框 “配置連接 - QtDesigner”,對話框的左側和右側分別是控件對象 “checkBox_4” 的信號和槽函數(shù)。
- 從對話框左側選中 “clicked(bool)”;
- 從對話框右側選中 “setChecked(bool)”;
- 點擊對話框下方的按鈕 “OK”,完成該信號/槽連接的配置。
2.4 信號與槽的連接:發(fā)送者是動作對象
常見的信號發(fā)送者是圖形窗口中的各種控件對象,但也可以是動作對象。本例介紹對菜單欄和工具欄中控件對象建立信號與槽的連接。
信號的發(fā)送者是動作對象時,信號的接收者通常是頂層對象 “MainWindow”,而槽函數(shù)可以是對象 “MainWindow” 的內置函數(shù),也可以是自定義函數(shù)。
在上一篇文章中我們曾為菜單欄和工具欄中的動作 “actionQuit” 建立信號/槽連接,就是發(fā)送者是動作對象、連接到對象 “MainWindow” 的內置函數(shù)的案例。其操作過程如下:
- 從在 QtDesigner 右側下方窗口 “信號/槽編輯器”,點擊綠色的 “+” 新建一個信號/槽連接;
- 點擊 “<發(fā)送者>”,從菜單中選擇對象 “actionQuit”;
- 點擊 “<信號>”,從菜單中選擇 “triggered()”;
- 點擊 “<接收者>”,從菜單中選擇 “MainWindow”;
- 點擊 “<槽>”,從菜單中選擇 “closed()”。
以上操作的作用是:發(fā)送者 對象 “actionQuit” 觸發(fā) “triggered()” 時,接收者 對象"MainWindow" 執(zhí)行槽函數(shù) “closed()”。
下面我們再為另一個動作 “actionHelp” 建立信號/槽連接,連接的槽函數(shù)為自定義函數(shù) trigger_actHelp()。其操作過程如下:
- 在 QtDesigner 將自定義函數(shù) trigger_actHelp() 添加到槽函數(shù)配置連接表中;
- 從在 QtDesigner 右側下方窗口 “信號/槽編輯器”,點擊綠色的 “+” 新建一個信號/槽連接;
- 點擊 “<發(fā)送者>”,從菜單中選擇對象 “actionHelp”;
- 點擊 “<信號>”,從菜單中選擇 “triggered()”;
- 點擊 “<接收者>”,從菜單中選擇 “MainWindow”;
- 點擊 “<槽>”,從菜單中選擇 “trigger_actHelp()”。
至此,本章介紹了用 QtDesigner 進行幾種常見的信號/槽連接的編輯和設置方法。如下圖所示,在 QtDesigner 中所添加的信號/槽連接都會在信號/槽編輯器窗口內顯示。
3. 圖形界面的主程序
上節(jié)在 QtDesigner 中完成了圖形界面的設計,將該文件另存為 uiDemo4.ui。打開 PyCharm,選中文件 uiDemo4.ui,使用 PyUIC 可以將其轉換為 uiDemo4.py。
接下來我們要編寫圖形界面的主程序,調用圖形界面設計文件 uiDemo4.py。
3.1 從面向過程到面向對象
面向過程的程序設計
在上一篇文章中,我們在主程序中創(chuàng)建主窗口后,直接調用 UI 中的 Ui_MainWindow()。這是面向過程的程序設計方法。
# GUIdemo3.py import uiDemo3 # 導入圖像界面設計文件 if __name__ == '__main__': app = QApplication(sys.argv) # 創(chuàng)建應用程序對象 MainWindow = QMainWindow() # 創(chuàng)建主窗口 ui = uiDemo3.Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() # 顯示主窗口 sys.exit(app.exec_()) # 在主線程中退出
面向對象的程序設計
隨著項目的不斷深入,需要處理更加豐富的圖形界面和實現(xiàn)更加復雜的軟件功能,程序的規(guī)模越來越大,程序的結構越來越復雜。
面向對象的程序設計使程序的結構更加清晰,從而易于閱讀、理解、開發(fā)和維護,非常適合開發(fā)大規(guī)模、多任務的圖形界面應用軟件。PyQt5 中的類、對象、控件和方法,都是面向對象的程序設計的概念。因此,從本文開始我們采用面向對象的程序設計方法,來編寫圖形界面的主程序。
例程 GUIdemo4.py 如下:
from uiDemo4 import Ui_MainWindow # 導入 uiDemo4.py 中的 Ui_MainWindow 界面類 class MyMainWindow(QMainWindow, Ui_MainWindow): # 繼承 QMainWindow類和 Ui_MainWindow界面類 def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) # 初始化父類 self.setupUi(self) # 繼承 Ui_MainWindow 界面類 if __name__ == '__main__': app = QApplication(sys.argv) # 在 QApplication 方法中使用,創(chuàng)建應用程序對象 myWin = MyMainWindow() # 實例化 MyMainWindow 類,創(chuàng)建主窗口 myWin.show() # 在桌面顯示控件 myWin sys.exit(app.exec_()) # 結束進程,退出程序
在上面這個例程中,我們創(chuàng)建了一個類 MyMainWindow(),它繼承了 QtWidgets.QMainWindow 類方法和導入的 uiDemo4.py 中的 Ui_MainWindow 界面類。
super(MyMainWindow, self).init()
:初始化父類,把 MyMainWindow 的對象 self 轉成父類 QMainWindow 對象,并調用 init 函數(shù)。
self.setupUi(self)
:繼承 uiDemo4.py 中的 Ui_MainWindow 界面類,調用 Ui_MainWindow 類的setupUi() 方法。
不熟悉面向對象程序設計的小白,如果看不懂這段程序也沒有關系,保存下來照貓畫虎就可以了。
3.2 自定義槽函數(shù)
運行例程 GUIdemo4.py。咦,報錯了:
AttributeError: ‘MyMainWindow' object has no attribute ‘click_pushButton_2'
系統(tǒng)提示找不到 ‘click_pushButton_2',這是因為在主程序中還沒有編寫 2.2 中自定義的槽函數(shù)。
將自定義的槽函數(shù) click_pushButton_2()、click_pushButton_3、trigger_actHelp(self) 添加到主程序中。下面給出例程 GUIdemo4.py 完整的代碼。
# GUIdemo4.py # Demo4 of GUI by PyQt5 # Copyright 2021 youcans, XUPT # Crated:2021-10-10 import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox from uiDemo4 import Ui_MainWindow # 導入 uiDemo4.py 中的 Ui_MainWindow 界面類 class MyMainWindow(QMainWindow, Ui_MainWindow): # 繼承 QMainWindow類和 Ui_MainWindow界面類 def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) # 初始化父類 self.setupUi(self) # 繼承 Ui_MainWindow 界面類 def click_pushButton_2(self): # 點擊 pushButton_2 觸發(fā) self.lineEdit_2.setText("click_pushButton_2") return def click_pushButton_3(self): # 點擊 pushButton_3 觸發(fā) from datetime import datetime # 導入 datetime 庫 nowDate = datetime.now().strftime("%Y-%m-%d") # 獲取當前日期 "2021-10-10" nowTime = datetime.now().strftime("%H:%M:%S") # 獲取當前時間 "16:58:00" self.lineEdit_1.setText("Current date: {}".format(nowDate)) # 顯示日期 self.lineEdit_2.setText("Current time: {}".format(nowTime)) # 顯示時間 self.lineEdit_3.setText("Demo4 of GUI by PyQt5") # return def trigger_actHelp(self): # 動作 actHelp 觸發(fā) QMessageBox.about(self, "About", """數(shù)字圖像處理工具箱 v1.0\nCopyright YouCans, XUPT 2021""") return if __name__ == '__main__': app = QApplication(sys.argv) # 在 QApplication 方法中使用,創(chuàng)建應用程序對象 myWin = MyMainWindow() # 實例化 MyMainWindow 類,創(chuàng)建主窗口 myWin.show() # 在桌面顯示控件 myWin sys.exit(app.exec_()) # 結束進程,退出程序
現(xiàn)在我們就得到了一個雖然簡單但是很完整的面向對象的圖形界面應用程序 GUIdemo4。
檢查一下應用程序 GUIdemo4 的各項功能:
- 點擊 “1# 按鈕”,清空 “文本編輯行-1”;
- 點擊 “2# 按鈕”,在 “文本編輯行-2” 顯示:“click_pushButton_2”;
- 點擊 “3# 按鈕”,在 “文本編輯行-1” 顯示當前日期,在 “文本編輯行-2” 顯示當前時間,在 “文本編輯行-3” 顯示: “Demo4 of GUI by PyQt5”;
- 點擊 “4# 按鈕”, “4# 按鈕” 的選項框被選中;
- 點擊工具欄中的 “幫助”,彈出上圖中的信息提示框,點擊 “OK” 可以關閉信息框;
- 點擊菜單欄或工具欄中的 “退出”,關閉圖形窗口應用程序。
如果以上測試都成功了,那么恭喜小白同學,你已經掌握了用 QtDesigner 設計 PyQt5 圖形界面的基本功能。
在下一篇文章中,我們將介紹 PyQt5 中的常用控件。
傳送門 Python深度學習實戰(zhàn)PyQt5基本控件使用解析
以上就是Python深度學習實戰(zhàn)PyQt5信號與槽的連接的詳細內容,更多關于PyQt5項目的資料請關注本站其它相關文章!
版權聲明:本站文章來源標注為YINGSOO的內容版權均為本站所有,歡迎引用、轉載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內容涉嫌侵權,請聯(lián)系alex-e#qq.com處理。