PyQt GUI–信号与槽

目录

  • 目录
  • 前言
  • 系统软件
  • GUI的主循环
  • 信号与槽
  • 信号的应用
    • 使用控件类的内建信号
    • 自定义信号
    • 带参数的信号
  • 槽的应用
    • 创建槽
  • 信号和槽的连接
  • 最后

前言

PyQt中的信号和槽,就是一个触发和执行的关系。

系统软件

  • 系统
    • Win 10
  • 软件
    • Python 3.4.3
    • IPython 4.0.0
    • PyCharm 5
    • PyQt 4

GUI的主循环

在理解信号和槽之前,首先先了解GUI的实现过程。
GUI程具有事件驱动的特性,当一个GUI程序完成了初始化启动后,就会进入一个”服务器式”的无限循环中。在PyQt中使用作为进入主循环的标志。进入了主循环后,在这个循环周期中GUI程序会等待事件、处理事件、然后返回等待下一个事件。这通常是最后一行代码,一旦进入了主循环,GUI程序从此获得了控制权。自此之后,GUI程序的所有动作都交由callback来处理。而Qt中的信号和槽就是GUI程序中事件触发和callback之间的通信机制。极大的简化了指针调用在GUI程序中的复杂实现。

信号与槽

信号(Signal)和槽(Slot)是一种高级接口,应用于QObject间的通信。在GUI开发中,窗口控件会有一个回调函数(callback)用于响应因其自身的状态改变而触发的动作。i.e.:当QObject的状态被改变,信号就由该QObject发射(emit)出去,而且为了做到信息封装,QObject并不关注发送之后的事情。 槽用于接收信号并执行动作,是一个对象的成员方法,能够直接被调用。同样的,槽也并不关注有哪个信号与自己连接。信号和槽能够进行任意数量和任意类型的参数传递,但信号和槽的参数个数与类型必须一致,并且槽的参数类型不能为缺省参数。
信号Signal
信号都可以被QObject包含,当QObject的状态发生改变时(e.g. Button被Clicked、QWidget被Clicked),QObject指定的信号就会被发射。而且信号自身并不知道那个槽会接收自己,QObject只管发射信号。当一个信号被发射时,与其连接的槽将被立刻执行,就象一个正常的函数调用一样。
只有当与信号连接的所有槽都返回了以后,信号发射函数(emit)才会被返回。 如果存在多个槽与某个信号连接,当这个信号被发射时,这些槽将会无序的逐一执行,它们执行的顺序将会是随机的、不确定的,不能人为设定。在PyQt的窗体控件类中已经有很多内置的信号,当然你也可以自己定义信号。
槽:
在PyQt中的槽就是一个经过装饰器@QtCore.pyqtSlot()处理过的成员方法。槽唯一的特殊性就是可以与多个信号连接。当与其连接的信号被发射出来时,这个槽就会接受信号并被调用。
信号与槽连接的方式:
1)多个信号可以与单个的槽连接
2)单个信号也可以与多个的槽进行连接
3)一个信号可以与另外一个信号连接,这时无论第一个信号什么时候发射,系统都将立刻再发射与之关联的第二个信号。
连接的状态:
1)可以能会直接连接(同步,一对一)或排队等待连接(异步,多对一)
2)连接可能会跨线程
3)信号可能会断开
总结:
1. 类型安全:只有参数匹配的信号与槽才可以连接成功(信号的参数可以更多,槽会忽略多余的参数)。
2. 线程安全:通过借助QT自已的事件机制,信号槽支持跨线程并且可以保证线程安全。
3. 松耦合:信号不关心有哪些或者多少个对象与之连接;槽不关心自己连接了哪些对象的哪些信号。这些都不会影响何时发出信号或者信号如何处理。
4. 信号与槽是多对多的关系:一个信号可以连接多个槽,一个槽也可以用来接收多个信号。

Example:

这个例子还可以有这一种写法(调用连接方法的另一个方式):

在上面的两个例子中,连接信号clicked()与callback showMsg。这是使用成员方法作为槽的例子,在实际的项目中这并不是一个理想的写法。

PyQt GUI--信号与槽

自定义信号

信号类
class pyqtSignal(builtins.object)
| pyqtSignal(*types, name=str) -> signal
不定长形参指定信号需要传递的参数类型,PyQt中的Signal可以接受任意Python数据类型。

Example1

为了发射自定义的信号, 需要对QPushButton进行封装, 实例化创建button对象时自动绑定myclicked()信号 。封装QPushButton让他在收到点击信号的同时发送myclicked()信号。在实际项目中,对信号进行封装是一件很有必要的事情,能够让整个项目更加的模块化和易于维护。
Example2:另外一种写法

注意:上述两种写法效果是一样的,但是实现的本质却不一样。
Example1中定义了一个新的signalObject,并且通过call signalObject.emit()来发送信号对象自身。
Example2中没有定义新的signalObject,而是连接了信号clicked()和”槽”(使用成员方法代替槽)emitClicked(),最后通过”槽”将信号(str)发射出去。

PyQt GUI--信号与槽

另一种写法

这里写图片描述

Example2

来源:范桂飓

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2016年1月23日
下一篇 2016年1月23日

相关推荐