美文网首页
PyQt5编程(11):信号与事件的处理—指定信号处理程序

PyQt5编程(11):信号与事件的处理—指定信号处理程序

作者: 用电热毯烤猪 | 来源:发表于2018-01-01 21:22 被阅读0次

    所有的GUI应用程序都是基于事件驱动的。事件主要由应用程序的用户产生,但也可以由其他方式生成。
    比如,网络连接,定时器。为了对事件作出响应,系统会产生一个特定的信号。这个信号可视为PyQt库中系统事件的代表。
    要处理信号,需将一个类的函数或方法(PyQt中称之为"slot")与之相关联。当事件触发时,该函数或方法被调用,成为信号 的处理程序。
    使用继承自QObject类的connect()方法来指定信号的处理程序。调用格式为:

    connect(slot[, type=PyQt5.QtCore.Qt.AutoConnection[, no_receiver_check=False]])

    参数:
    slot – 可调用的函数或另一个信号
    type – 要连接的类型。程序应用到多线程编程时,要特别注意这个参数。type的可选值有:
    AutoConnection,0:默认值。
    如果信号和处理程序在同一线程,等同于DirectConnection;如果不在同一线程,则等同于QueedConnection。
    DirectConnection, 1:
    信号触发后,处理程序立即在源数据流(source stream)中执行。
    QueuedConnection, 2:
    信号触发后进行处理队列,处理程序在信号接收方执行。
    BlockingQueuedConnection, 4:
    类似于QueuedConnection,但在处理程序执行时,线程处于阻塞状态 。需要注意的是信号和处理程序必须在不同线程。UniqueConnection,0x80:表明处理程序只能指定一次。该值可以和前面的值进行组合应用。
    no_receiver_check – suppress the check that the underlying C++ receiver instance still exists and deliver the signal anyway.(禁止检查底层C ++接收器实例是否仍然存在,并传递信号。)

    例1:

    将on_clicked_button ()函数作为button按钮clicked信号处理程序的代码:
    button.clicked.connect(on_clicked_button)
    信号可以有不同数量的参数,参数可以为任何类型。在一个类中,可以存在信号名相同,但参数不同的多个信号。这时的调用方式为在信号之后加方括号([ ]) ,方括号内为接收到的数据类型。可以采用类型符号或该类型的英文字符串。
    button.clicked[bool].connect(on_clicked_button)
    button.clicked["bool].connect(on_clicked_button)
    可以给一个信号指定多个处理程序。见下例:

    # -*- coding: utf-8 -*-
    from PyQt5 import QtWidgets
    import sys
    
    def on_clicked():
        print("按钮按下: on_clicked ()被调用")
    
    class MyClass():
    
        def __init__(self, x=0):
            self.x = x
    
        def __call__(self):
            print("按钮按下: MyClass .__ call __ ()")
            print("x =", self.x)
    
        def on_clicked(self):
            print("按钮按下: MyClass.on_clicked ()")
    
    obj = MyClass()
    app = QtWidgets.QApplication(sys.argv)
    button = QtWidgets.QPushButton("点击鼠标")
    # 指定处理程序
    button.clicked.connect(on_clicked)
    # 指定处理程序为类的方法
    button.clicked.connect(obj.on_clicked)
    # 指定处理程序为类实例
    button.clicked.connect(MyClass(10))
    # 指定处理程序为匿名函数
    button.clicked.connect(lambda: MyClass(5)())
    button.show()
    sys.exit(app.exec_())
    

    程序的输出为:
    按钮按下: on_clicked ()被调用
    按钮按下: MyClass.on_clicked ()
    按钮按下: MyClass .__ call __ ()
    x = 10
    按钮按下: MyClass .__ call __ ()
    x = 5

    PyQt5中有很多函数可作为信号的处理程序,这些函数称之为slot。
    只要在函数定义前加上装饰符@pyqtSlot,任何自定义函数都可变为slot。格式为:
    @pyqtSlot(types[, name[, result]])
    types – the types that define the C++ signature of the slot. Each type may be a Python type object or a string that is the name of a C++ type(定义slot的C++签名。类型可以是Python的类型也可以是C_++类型的英文字符串).

    name – the name of the slot that will be seen by C++. If omitted the name of the Python method being decorated will be used.(C++中可见的slot名称. 如果省略,将使用被装饰的函数名. )

    result – the type of the result and may be a Python type object or a string that specifies a C++ type. (函数结果的类型。可以是Python的类型也可以是C_++类型的英文字符串)

    例2:

    # -*- coding: utf-8 -*-
    from PyQt5 import QtCore, QtWidgets
    import sys
    
    class MyClass(QtCore.QObject):
    
        def __init__(self):
            QtCore.QObject.__init__(self)
    
        @QtCore.pyqtSlot()
        def on_clicked(self):
            print("按钮按下. slot on_clicked()")
    
        @QtCore.pyqtSlot(bool, name="myslot")
        def on_clicked2(self, status):
            print("按钮按下. slot myslot(bool)", status)
    
    obj = MyClass()
    app = QtWidgets.QApplication(sys.argv)
    button = QtWidgets.QPushButton("点击鼠标")
    button.clicked.connect(obj.on_clicked)
    button.clicked.connect(obj.myslot)
    button.show()
    sys.exit(app.exec_()) 
    

    程序输出:
    按钮按下. slot on_clicked()
    按钮按下. slot myslot(bool) False

     PyQt中没有强制将信号的处理函数转化成slot,但推荐这样做,因为调用slot的速度快。

    相关文章

      网友评论

          本文标题:PyQt5编程(11):信号与事件的处理—指定信号处理程序

          本文链接:https://www.haomeiwen.com/subject/odkxnxtx.html