第15.19節 PyQt(Python+Qt)入門學習:自定義信號與槽連接

一、引言

本文利用中介紹了PyQt中的信號和槽機制,除了使用PyQt組件的已有信號外,PyQt和Qt一樣支持自定義信號。本節將介紹自定義信號及其他信號、槽的高級特性。

二、自定義信號的簡單例子

2.1、案例說明

在一個圖形界面類中類變量內定義一個信號selfSig,在類的實例方法中定義一個方法sigRecv作爲槽函數接收信號、在構造方法中完成信號和槽的連接。

爲了發送信號,在圖形界面中有個名爲emitSig的信號發送按鈕,在Designer中進行了按鈕的clicked信號和槽函數emitSigStart的關聯。當按下按鈕時,將按鈕後面輸入行中的內容發送出去,emitSigStart槽函數則將接收到的內容在顯示窗w_displayInf中顯示。

案例的主程序名爲sigApp.py,圖形界面文件爲:ui_mainWin.ui,圖形界面生成的代碼爲ui_mainWin.py,圖形界面生成代碼的類名爲:Ui_w_mainWin。zaipycharm的工程文件截圖:
在這裏插入圖片描述

2.2、案例運行截圖

在這裏插入圖片描述

2.3、案例主程序代碼

# -*- coding: utf-8 -*-

import sys
from PyQt5 import QtWidgets,QtCore,QtGui
import ui_mainWin

class w_mainWin(ui_mainWin.Ui_w_mainWin,QtWidgets.QWidget):
    selfSig = QtCore.pyqtSignal(str) #定義信號,帶一個str類型的參數

    def __init__(self): #構造方法
        super(w_mainWin, self).__init__()
        self.setupUi(self)
        self.selfSig[str].connect(self.sigRecv) #連接信號和槽

    def emitSigStart(self): #圖形界面按鈕clicked信號的槽函數
        info = self.sigInfo.text()
        self.selfSig[str].emit(info)

    def sigRecv(self,info): #接收信號的槽函數
        self.w_displayInf.append(f"Received sinal:{info}")

三、自定義信號的案例詳解

上面介紹的案例,是一個類內的信號和槽函數綁定,如果要實現類似功能,完全無需通過自定義信號和槽的機制來實現,直接點擊按鈕將輸入行內文本添加到顯示窗就可以,但通過這個案例可以比較清楚的知道PyQt中自定義信號及使用的過程,當信號和槽不在一個對象時相關步驟及方法是一樣的,只是連接時的對象名不同,沒有本質區別。

3.1、定義信號

3.1.1、語法

定義信號的本質就是在類體中使用QtCore.pyqtSignal定義一個類變量,QtCore.pyqtSignal的完整語法如下:

PyQt5.QtCore.pyqtSignal(types[, name[, revision=0[, arguments=[]]]])

上面案例的信號定義在類開始處:

selfSig = QtCore.pyqtSignal(str) #定義信號,帶一個str類型的參數

3.1.2、參數釋義

  • types :定義信號的C++簽名(函數簽名由參數個數與其類型組成。函數在重載時,利用函數簽名的不同即參數個數與類型的不同來區別調用者到底調用的是那個方法)的類型。每種類型都可以是Python類型對象,也可以是一個C++類型的字符串,或者,每一個都可以是一個序列(如列表)類型參數,在這種情況下,每個序列定義不同信號重載的簽名,即同一個信號名有不同簽名(即信號名相同、簽名不同的重載信號),每個簽名是一序列類型,第一個序列將是重載缺省簽名。

  • name:信號名字,如果信號名就是類變量名則可以省略該參數,由於types參數是可變的,因此本參數使用必須通過關鍵字參數方式傳值,即name=‘信號名’方式

  • revision、arguments:都是關鍵字參數,用於輸出到QML使用,QML是Qt使用的一種類似css和js功能疊加的腳本語言,老猿沒準備學習和介紹,因此這兩個參數在此就不關注了。

3.1.3、返回值

pyqtSignal定義返回的就是一個信號,但這時的信號與普通的類變量差不多,並沒有信號相關的方法。以上例爲例,在信號定義返回後調試模式下觀察selfSig這個變量的情況,如圖(因爲是類變量,所以必須帶類名觀察):
在這裏插入圖片描述

3.2、信號與槽的連接

3.2.1、語法

自定義信號與槽的連接與PyQt內部定義信號與槽的連接本質上是一樣的,都是調用信號的connect方法,相關方法語法如下:
connect(slot[, type=PyQt5.QtCore.Qt.AutoConnection[, no_receiver_check=False]])

上面案例中的連接語句在構造方法內,如下:

self.selfSig[str].connect(self.sigRecv) #連接信號和槽

3.2.2、參數釋義

  • slot:信號需要連接的槽,可以是一個與信號匹配的某個對象的回調方法、也可以是一個已經綁定的有相同簽名的其他信號
  • type:連接的類型,其類型爲枚舉類型Qt.ConnectionType,有如下種取值: 在這裏插入圖片描述
  • no_receiver_check:如果爲True,禁止檢查下層的C++接收對象實例是否還存在,不管怎樣都要發出信號,默認值爲False。

3.2.3、返回值

connect調用後,如果正常返回,則返回對象爲一個 Connection對象,這個對象在 當要執行disconnect斷開信號與槽的連接時使用,這是斷開信號與一個lambda函數的連接的唯一方法。

3.3、發射信號

發射信號非常簡單,就是調用信號的方法emit。語法如下:
emit(*args)
參數args:傳遞給所有連接槽的可選參數序列。

上面案例的發射信號語句如下:

self.selfSig[str].emit(info)

四、小結

本節通過一個簡單案例介紹了PyQt中怎麼自定義一個信號、怎麼連接一個信號,當信號定義好以後,就與Qt內置信號沒有本質的區別,如果將信號所在對象通過相關方法定義成一個Qt Designer的插件時,信號就能在Designer中直接可見和操作。

更多關於信號和槽的內容請參考《 專欄:使用PyQt開發圖形界面Python應用》中《第六章 信號和槽進階–自定義信號及其他信號、槽的高級特性》的內容。

老猿Python,跟老猿學Python!

發佈了623 篇原創文章 · 獲贊 3419 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章