信号和槽是一种高级接口,应用于对象之间的通讯,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。它为高层次的事件处理自动生成所须要的附加代码。在咱们所熟知的不少 GUI 工具包中,窗口小部件 (widget) 都有一个回调函数用于响应它们能触发的每一个动做,这个回调函数一般是一个指向某个函数的指针。可是,在 QT 中信号和槽取代了这些凌乱的函数指针,使得咱们编写这些通讯程序更为简洁明了。
全部从 QObject 或其子类 ( 例如 Qwidget) 派生的类都可以包含信号和槽。当对象改变其状态时,信号就由该对象发射 (emit) 出去,这就是对象所要作的所有事情,它不知道另外一端是谁在接收这个信号。这就是真正的信息封装,它确保对象被看成一个真正的软件组件来使用。槽用于接收信号,但它们是普通的对象成员函数。一个槽并不知道是否有任何信号与本身相链接。并且,对象并不了解具体的通讯机制。
你能够将不少信号与单个的槽进行链接,也能够将单个的信号与不少的槽进行链接,甚至于将一个信号与另一个信号相链接也是可能的,这时不管第一个信号何时发射系统都将马上发射第二个信号。总之,信号与槽构造了一个强大的部件编程机制。
说实话对于像我这样的新手来讲看着就蛋疼,想学会它没办法,咱们仍是简化一下概念吧:
全部QObject类均可以使用信号槽,换句话来讲继承自pyqt中的类基本上均可以使用信号槽机制。固然非QObject也是能够经过其余一些办法来使用信号槽的。
仅仅有了信号和槽是不行的,咱们还须要了解:
信号(Signal)、槽(slot)、链接(connect)、动做事件(action)、发射(emit)、发送者、接受者等等一些列的知识。好吧,别搞的那么复杂行不行,咱们仍是学学该怎么用吧。
python
在Qt Designer中为咱们提供了一些基本的信号槽方法,咱们来看看:编程
点击工具栏上的“编辑信号/槽”,进入信号槽编辑模式,咱们能够直接在发送者(button)上按住鼠标左键不放,拖动到接收者(Form窗体)上。这样就创建起了链接。
app
接着,会弹出配置链接对话框。函数
左边是发送者(按钮)的信号(动做事件),右边是接收者(窗体)的槽(动做事件)工具
如图所示,我信号选择的是clicked,槽选择的是closeui
咱们看一下编译后生成的代码:
self.quitButton.clicked.connect(Form.close)
spa
实现的功能是:当按钮点击以后关闭窗体。
流程:按钮是信号发送者,当点击按钮以后会发送一个信号出去,经过这段代码程序内部的通信机制知道这个按钮的点击事情被链接到窗体的关闭事件上去了,而后通知接受者窗体,你该运行槽函数close了!
.net
那么咱们怎么能执行本身的“槽”呢?
指针
[python] view plain copy print?code
from PyQt5 import QtWidgets
from untitled import Ui_Form
class mywindow(QtWidgets.QWidget,Ui_Form):
def __init__(self):
super(mywindow,self).__init__()
self.setupUi(self)
self.myButton.clicked.connect(self.myPrint) #槽函数不用加括号
def myPrint(self): #定义槽
print("helloWorld")
if __name__=="__main__":
import sys
app=QtWidgets.QApplication(sys.argv)
myshow=mywindow()
myshow.show()
sys.exit(app.exec_())
from PyQt5 import QtWidgets from untitled import Ui_Form class mywindow(QtWidgets.QWidget,Ui_Form): def __init__(self): super(mywindow,self).__init__() self.setupUi(self) self.myButton.clicked.connect(self.myPrint) #槽函数不用加括号 def myPrint(self): #定义槽 print("helloWorld") if __name__=="__main__": import sys app=QtWidgets.QApplication(sys.argv) myshow=mywindow() myshow.show() sys.exit(app.exec_())
槽其实就个函数(方法),Qt5中的槽函数不在限定必须是slot,能够是普通的函数、类的普通成员函数、lambda函数等。编译期间就会检查信号与槽是否存在! 信号的connect链接最好放在__init__析构函数里面,这样只会声明一次链接,若是在类方法(函数中)使用的话,要记得disconnect,不然connect会链接屡次,致使程序异常。 信号槽函数不用加 (),不然可能会致使链接异常。