信号和槽

时间:2023-01-31 07:56:16


信号和槽的基本概念及关联

 

用于事件的传递。类似于中断回调。

基于GUI的程序,由类似 按下 button、鼠标点击等event来驱动。在pyqt中,widgets被设计为这些事件的源。每个pyqt widgets被设计用来发射(emit)’Signal’,以响应一个或多个事件。

   信号本身并不处理具体的事件,而仅仅将事件转发到对应的 ‘slot’上,而slot实际上就是一个处理函数而已。

  建立控件、信号和槽 关系的接口如下:

  1. QtCore.QObject.connect(widget, QtCore.SIGNAL(‘signalname’), slot_function)

表明connect在QObject中定义的。

2)更加直观的方式,此种方式应用更多:

widget.signal.connect(slot_function)

假设当button被按下时,产生clicked信号,此信号被链接到一个python接口函数,此流程可以通过下面两种接口之一实现:

QtCore.QObject.connect(button, QtCore.SIGNAL(“clicked()”), slot_function)

button.clicked.connect(slot_function)

信号和槽

 

 

 

 

信号的产生

通过第一节,可以看到信号隶属于控件。那么信号如何产生呢?什么样的变量会被注册到pyqt的信号-槽机制中?

信号的定义: New signals can be defined as class attributes using the ​​pyqtSignal()​​ factory.

信号和槽

返回新的信号。参数可以指定槽函数的参数类型,以便事件源在信号发射时,将此类型的参数传递给槽函数

信号和槽

 

信号定义的实例:

  1. 一个继承自QObject的类中,定义了三个信号,每个信号的参数类型不同。

非常重要的一点:虽然看起来此类仅仅三个变量,可以将三个变量挪移到实际的业务类中,但是此处最关键的是继承自QObject类。

class WorkerSignals(QObject):
'''
Defines the signals available from a running worker thread.
'''
finished = pyqtSignal()
error = pyqtSignal(tuple)
progress = pyqtSignal(float)

例如直接将信号定义在业务类中

Class checkWorker(QRunnable):
checkFinished=pyqtSignal()
other code…..
worker=checkWorker()
worker.checFinished.connect(SlotFunc)

此时会报错: cannot be converted to PyQt5 OtCore.QObject in this context

2)在具体的事件处理中,比如movemouse中,可以针对这三个信号发射

self.signals.progress.emit(n / total_n)
exctype, value = sys.exc_info()[:2]
self.signals.error.emit((exctype, value, traceback.format_exc()))
self.signals.finished.emit()

3)在代码初始化化或者任何2)中事件产生前的接口中将信号和slot建立关联

self.signals.progress.connect(self.update_progress)
self.signals.finished.connect(self. _finished)
self.signals.error.connect(self._error)

 

 

槽函数的注册

在上面最后一节中,描述了建立槽函数和信号的对应关系。

self.signals.error.connect(self._error)

 

 

 

 

 

 

 

假如此注册接口被调用两次,则实际上当error事件产生时,self._error函数会被调用两次。这就要求我们在编写代码时,一定注意同一个槽函数不要多次注册。

比如我们把注册槽函数的过程放到按钮处理流程中,每次按下则注册槽函数,此时如果不加以控制,每次按下按钮,同一个信号就会增加一次注册函数,最终导致同一个信号有很多个相同的槽函数。

 

参考资料

​http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html#PyQt5.QtCore.pyqtSignal​​ pyqt5