PyQt5 中信号signal 与 槽 slot 的相关知识 – zhangji

博文视点 本文写得澄清 重印获知 感激

单位:qt,全部QObject物体和PyQt中拿承继自QWidget的支配权(这些都是QObject的子物体)都伴奏信号与槽机制。当信号被方法时,衔接的插槽功用将非本意的动作履行。在PyQt 5中信号与槽经过()方法衔接。

Pyqt的窗口把持类有数量庞大的数量庞大的内置信号,形成人员还可以添加自精确地解说信号。信号和插槽具有以下特点。

  • 一体信号可以衔接多个插槽。
  • 一体信号可以衔接到另一体信号。
  • 信号限制因素可以是一点python典型。
  • 一体插槽可以监督多个信号。
  • 信号与插槽可同时存在的衔接,它也可以是异步衔接。
  • 信号到插槽的衔接可能性会经过楼梯的一段。
  • 信号可能性断开。

在GUI计划中,更改支配权的州时(如单击使系牢之物,通常你必要预示另一体公司,即,应验了物体当射中靶子传达。在最初的图形用户交界面计划中运用了什么回调机制(是什么回调机制),执意很查一下?),单位:qt则运用一种新机制——信号与槽。写具有某个时代特征的,率先精确地解说这种信号和时隙,在类中信号与槽举行衔接,应验物体当射中靶子记录方法。信号及槽机构示意图如图1所示。
在这里插入图片描述
当事情或许州发生方法时,就会收回信号。同时,信号会春季拿与执意很事情(信号)相关性的作用(槽)。信号与槽可以是多对多的相干。一体信号可以衔接多个插槽,一体槽也可以监听多个信号 。

平稳的的上品自精确地解说信号与槽,指的是we的所有格形式可以以它自己如同的方法精确地解说信号与槽作用,并发表限制因素。自精确地解说信号的普通流出如次:

(1)精确地解说信号。

(2)精确地解说槽作用。

(3)衔接信号与槽作用。

(4)开枪信号。

1.精确地解说信号

经过类身体部位变量精确地解说信号物体。

class MyWidget(QWidget):  
    # 无限制因素的信号
    Signal_NoParameters = pyqtSignal()     
    # 带限制因素的信号(整体      
    Signal_OneParameter = pyqtSignal(int)         
    # 限制因素(整体或字母行)的强调版本的信号        
    Signal_OneParameter_Overload = pyqtSignal([利钱],[战术]  
    # 有两个限制因素(整体,串信号)      
    Signal_TwoParameters = pyqtSignal(int,和解)    
    # 有两个限制因素([整体,整体]或[整体],字母行强调版本的信号      
    Signal_TwoParameters_Overload = pyqtSignal([内地,利钱],[内地,和解] 

2.精确地解说槽作用
精确地解说槽作用,它有各自的卓越的的出口限制因素。

class MyWidget(QWidget):  
    def setValue_NoParameters(同一的):   
        限制因素槽作用  
        pass  

    def setValue_OneParameter(self,nIndex):   
        ''单限制因素槽作用(整体)'  
        pass

    def setValue_OneParameter_String(self,szIndex):   
        ''''''带一体限制因素(字母行)的槽作用''''''  
        pass 

    def setValue_TwoParameters(self,x,y):   
        ''''''有两个限制因素(整体,整体)的槽作用''''''  
        pass  

    def setValue_TwoParameters_String(self,x,szY):   
        ''''''有两个限制因素(整体,字母行)槽作用''''''  
        pass

3.衔接信号与槽作用

经过connect方法衔接信号与槽作用或许可呼唤物体。

app = QApplication()   
widget = MyWidget()   
# 衔接限制因素信号
( )                                          

# 用整体限制因素衔接信号
()                                         

# 运用整体限制因素衔接,过载信号
[利钱].
    connect()                              

# 运用整体限制因素衔接,过载信号
[战术]
    衔接(_字母行 )                     

# 衔接一体信号,它有两个整体限制因素
( )                                        

# 衔接有两个限制因素(整体,整体)署名的强调版本
[内地,利钱].
    connect( )                      

# 衔接有两个限制因素(整体,字母行强调版本的信号
[内地,和解]
    衔接(_字母行 )              
()  

四分经过章。开枪信号

开枪信号。

class MyWidget(QWidget):  

    def mousePressEvent(self, event):  
        # 开枪无限制因素的信号
        () 
        # 开枪带限制因素的信号(整体
        (1) 
        # 开枪带一体限制因素(整体)署名的强调版本
        (1)
        # 开枪带一体限制因素(字母行强调版本的信号
        ("abc")
        # 开枪有两个限制因素(整体,串信号)
        (1,"abc")
        # 开枪有两个限制因素(整体,整体)署名的强调版本
        (1,2)
        # 开枪有两个限制因素(整体,字母行强调版本的信号
         (1,"abc") 

5.窥测

此示例文章命名为PyQt5/Chapter07/,完全的加密如次:

from PyQt5.QtCore import QObject , pyqtSignal

class CustSignal(QObject):

    结算单限制因素信号
    signal1 = pyqtSignal()

    用int典型限制因素结算单信号
    signal2 = pyqtSignal(int)

    用int和str典型限制因素结算单信号
    signal3 = pyqtSignal(int,和解)

    用列表典型限制因素结算单信号
    signal4 = pyqtSignal(list)

    措辞典典型限制因素结算单信号
    signal5 = pyqtSignal(dict)

    结算单多个强调版本的信号,包含int和str典型限制因素的信号和str典型的信号
    signal6 = pyqtSignal([内地,和解], [战术]

    def __init__(self,parent=无)
        super(CustSignal,同一的).__init__(parent)

        将信号衔接到使具有特性的插槽功用
        ()
        ()
        ()
        ()
        ()
        [内地,和解]connect()
        [战术]connect(OverLoad)

        #开枪信号
        ()
        (1)
        (1,译文)。
        ([1,2,3,4])
        ({"name":"wangwu",年纪:25
        [内地,和解]emit(1,译文)。
        [战术]emit(译文)。

    def signalCall1(同一的):
        print("signal1 开枪)

    def signalCall2(self,瓦尔)
        print("signal2 emit,value:",瓦尔)

    def signalCall3(self,val,译文)
        print("signal3 emit,value:",val,译文)

    def signalCall4(self,瓦尔)
        print("signal4 emit,value:",瓦尔)

    def signalCall5(self,瓦尔)
        print("signal5 emit,value:",瓦尔)

    def signalCall6(self,val,译文)
        print("signal6 emit,value:",val,译文)

    def signalCall6OverLoad(self,瓦尔)
        print("signal6 overload emit,value:",瓦尔)

if __name__ == ''__main__'':  
    custSignal = CustSignal()

算是如次。:

signal1 emit
signal2 emit,value: 1
signal3 emit,value: 1 text
signal4 emit,value: [1, 2, 3, 4]
signal5 emit,value: 姓名 ''wangwu'', '年纪' ''25''}
signal6 emit,value: 1 text
signal6 overload emit,value: text

2 运用自精确地解说限制因素

在PyQt计划一道菜中,常常会不期而遇给槽作用发表自精确地解说限制因素的感染,譬如有一体信号与槽作用的衔接是

(show_page)

we的所有格形式发生四处走动的clicked信号来说,它是缺席限制因素的;四处走动的show_page作用来说,怀孕它可以接纳限制因素。怀孕show_page作用像如次很:

def show_page(self, name):
    print(name,"  点击啦")

去就发生一体成绩——信号收回的限制因素数字为0,槽作用接纳的限制因素数字为1,鉴于0<1,很运转起来一定会报错(报账是信号收回的限制因素数字一定要大于槽作用接纳的限制因素数字)。处置执意很成绩执意本条的强调:自精确地解说限制因素的发表。

本书为特定用途而打算了两种处置方法,到达一种处置方法是运用lambda表达。此示例文章命名为PyQt5/Chapter07/qt07_ winSignalSlot04.py ,完全的加密如次:

from PyQt5.QtWidgets import QMainWindow, QPushButton , QWidget , QMessageBox, QApplication, QHBoxLayout
import sys 

class WinForm(QMainWindow):  
    def __init__(self, parent=无)  
        super(WinForm, 同一的).__init__(parent)  
        button1 = QPushButton(''Button 1'')  
        button2 = QPushButton(''Button 2'')  

        (lambda: (1)) 
        (lambda: (2))

        layout = QHBoxLayout()  
        (button1)  
        (button2)  

        main_frame = QWidget()  
        (规划)       
        (main_frame)  

    def onButtonClick(self, n):  
        print(''Button {0} 被按下了''.format(n))  
        (self, "通讯准时的框", ''Button {0} clicked''.format(n))

if __name__ == "__main__":  
    app = QApplication()  
    form = WinForm()  
    ()  
    (())

运转本子,显示比分如图2和图3所示。
在这里插入图片描述
图2
在这里插入图片描述
图3

加密辨析:

单击“Button 1使系牢之物,音讯准时的框将敲击U,准时的通讯为button 1 clicked”。python把持台i的出口通讯:

Button 1 被按下了

这是枢要的解说 onButtonClick() 该功用方法处置因两个使系牢之物的信号。运用 lambda 表达将使系牢之物号发表给槽作用,自然,它还可以为特定用途而打算另一个一点东西,偶数的使系牢之物支配权它自己(想象槽作用企图更改。

另一体处置方案是 functools 射中靶子 partial 作用。此示例文章名为pyqt5/chapter0,小瘤加密如次:

(分离, 1))         
(分离, 2))

哪种方法好转的?这是作风成绩。,我更如同运用lambda表达,因它是有系统的的。,活泼。

3 修饰器信号和插槽

平稳的的修饰器信号和插槽,它经过修饰器来精确地解说信号和插槽功用。。详细运用方法如次:

@(限制因素)
def on_发送者物体称呼_开枪信号称呼(self, 限制因素):
        pass

此方法在以下作用已履行的事先准备下任务:

(QObject)

在是你这么说的嘛!加密中,运用了说话者物体称呼 setObjectName 功用设置称呼,像这样,自精确地解说槽作用的命名常客也可以凝视:on + 运用 setObjectName 设置称呼 + 信号称呼。接下来,看一眼方法运用它。。

此示例文章命名为PyQt5/Chapter07/,完全的加密如次:

from PyQt5 import QtCore 
from PyQt5.QtWidgets import QApplication  ,QWidget ,QHBoxLayout , QPushButton
import sys    

class CustWidget( QWidget ):

    def __init__(self, parent=无)
        super(CustWidget, 同一的).__init__(parent)

         = QPushButton("OK", 同一的)
        设置object name以设置物体称呼
        ("okButton")
        layout = QHBoxLayout()
        ()
        (规划)
        QtCore.(同一的)

    @()    
    def on_okButton_clicked(同一的):
        print( 单击决定使系牢之物)。

if __name__ == "__main__":        
    app =  QApplication()
    win = CustWidget()
    ()
    ()

运转本子,显示比分如图4所示。。单击决定使系牢之物,把持台标志出认为会发生的调试通讯。
在这里插入图片描述
图4

有些讲师可能性会注意到,we的所有格形式还缺席解说这行加密的意思。:

(QObject)

其实,它内脏 PyQt 5 中地面信号称呼非本意的动作衔接到插槽功用的小瘤加密。从上一章的容器中可以参观,运用 pyuic5 命令封爵的加密将具有很伙伴COD,过后解说一下。。

这行加密用于QObject射中靶子后代的稍微信号地面它物体称呼衔接到通信的的衔接线槽作用 。这句话读起来相反地艰深晦涩,下面是一体复杂解说的容器 。以下面容器射中靶子加密为例:

想象加密QtCore.(同一的)先前履行,过后是下面的加密:

@()    
def on_okButton_clicked(同一的):
    print( 单击决定使系牢之物)。

它将非本意的动作识别为以下加密(注,翻开从功用中切除,因 on 将受到 connectSlotsByName 的感染,加法 on 涌现运转时成绩):

def __init__(self, parent=无)
        .clicked.connect(_clicked)
    def okButton_clicked(同一的):
        print(单击决定使系牢之物)。

这分离加密放在PyQt5/Chapter07/文章中:

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

"""
    [简介]
    信号与插槽非本意的动作衔接示例
"""

from PyQt5 import QtCore 
from PyQt5.QtWidgets import QApplication ,QWidget ,QHBoxLayout , QPushButton
import sys    

class CustWidget( QWidget ):

    def __init__(self, parent=无)
        super(CustWidget, 同一的).__init__(parent)

         = QPushButton("OK", 同一的)
        设置object name以设置物体称呼
        ("okButton")        
        layout =  QHBoxLayout()
        ()
        (规划)                
        QtCore.(同一的)
        .clicked.connect(_clicked)

    def okButton_clicked(同一的):
        print( 单击决定使系牢之物)。

if __name__ == "__main__":        
    app =  QApplication()
    win = CustWidget()
    ()
    (())

运转是你这么说的嘛!加密,算是与图4平稳的。

4 信号和SLO的断开和衔接

间或出于一种报账,怀孕暂且或干后花的形状颜色不变的断开与SLO的信号。这执意本条射中靶子诉讼为特定用途而打算应验的目的。

此示例文章命名为PyQt5/Chapter07/,完全的加密如次:

from PyQt5.QtCore import QObject , pyqtSignal

class SignalClass(QObject):

     # 结算单限制因素信号
    signal1 = pyqtSignal()

    # 用int典型限制因素结算单信号
    signal2 = pyqtSignal(int)

    def __init__(self,parent=无)
        super(SignalClass,同一的).__init__(parent)

        # 将信号signal1衔接到sin1Call和sin2Call这两个槽作用
        ()
        ()

        # 将信号信号2衔接到信号信号信号
        ()

        # 开枪信号
        ()
        (1)

        # 断开signal1、信号2信号与插槽功用的衔接
        .disconnect()
        .disconnect()
        ()

        # 将信号signal1和signal2衔接到同一体槽作用sin1Call
        ()
        ()

        # 再开枪信号
        ()
        (1)

    def sin1Call(同一的):
        print("signal-1 开枪)

    def sin2Call(同一的):
        print("signal-2 开枪)

if __name__ == ''__main__'':  
    signal = SignalClass()

算是如次。:

signal-1 emit
signal-2 emit
signal-1 emit
signal-2 emit
signal-1 emit
signal-1 emit

5 多线索中信号与槽的运用

运用多线索的最复杂方法是运用qthread作用,以下加密(请请教PyQt5/Chapter07/ 显示了qthread作用与信号和插槽的复杂结成。完全的加密如次:

from PyQt5.QtWidgets import  QApplication ,QWidget
from PyQt5.QtCore import QThread ,  pyqtSignal
import sys

class Main(QWidget):
    def __init__(self, parent = 无)
        超等的(主,同一的).__init__(parent)

        # 创办线索窥测并设置NAM、变量、信号与槽
        self.thread = MyThread()
        ("thread1")
        ()
        (6)

    def outText(self,译文)
        print(译文)

class MyThread(QThread):
    sinOut = pyqtSignal(和解)

    def __init__(self,parent=无)
        super(MyThread,同一的).__init__(parent)
        self.identity = None

    def setIdentity(self,译文)
        self.identity = text

    def setVal(self,瓦尔)
         = int(瓦尔)
        # 履行线索的运转方法
        ()

    def run(同一的):
        while  > 0 and self.identity:
            # 开枪信号
            ("==>"+str())
             -= 1

if __name__ == ''__main__'':  
    app = QApplication()
    main = Main()
    ()
    (())

算是如次。:

thread1==>6
thread1==>5
thread1==>4
thread1==>3
thread1==>2
thread1==>1

间或,形成prog时通常会履行旷日持久的的手柄,这将理由乐器的吹口阻碍,这亦多线索的适合经过——处置执意很成绩,we的所有格形式可以创办多线索,用主线索重复强调乐器的吹口,运用子线索举行实时记录处置,顶点,算是显示在交界面上。。

本例中,精确地解说了配乐线索类backendthread来模仿配乐ti,信号重复强调日期在此线索clas中精确地解说。运用后端线索CLA在配乐处置记录,每秒钟发送一次自精确地解说信号重复强调日期。

设定初值窗口乐器的吹口时,精确地解说配乐线索类backendthrea,并把线索类的信号update_date衔接到槽作用handleDisplay()。因而配乐线索每回城市收回一体信号,就可以把最新的时期值实时显示在舞台窗口的QLineEdit译文对话框中。

此示例文章名为pyqt5/chapter0,完全的加密如次:

from PyQt5.QtCore import QThread ,  pyqtSignal,  QDateTime 
from PyQt5.QtWidgets import QApplication,  QDialog,  QLineEdit
import time
import sys

class BackendThread(QThread):
    # 经过类身体部位物体精确地解说信号
    update_date = pyqtSignal(和解)

    # 处置事情逻辑
    def run(同一的):
        while True:
            data = ()
            currTime = ("yyyy-MM-dd 时:分:秒)
            ( str(currTime) )
            (1)

class Window(QDialog):
    def __init__(同一的):
        (同一的)
        (''PyQt 5实时乐器的吹口重复强调示例'
        (400, 100)
        self.input = QLineEdit(同一的)
        (400, 100)
        ()

    def initUI(同一的):
        # 创办线索
        self.backend = BackendThread()
        # 衔接信号
        ()
        # 启动线索
        ()

    # 将现在的时期出口到译文bo
    def handleDisplay(self, 记录)
        (记录)

if __name__ == ''__main__'':
    app = QApplication()
    win = Window()
    () 
    (())

运转本子,显示比分如图5所示。。
在这里插入图片描述

发表评论

电子邮件地址不会被公开。 必填项已用*标注