赞
踩
信号和槽是用于对象之间的通信的,它们是Qt编程的基础,也是Qt的核心。它们可以让编程人员把那些互不了解的对象绑定在一起,来完成对象之间的协同操作。为此 Qt 引入了一些关键字,他们是slots、 signals、 emit,这些都不是 C++关键字,是 Qt 特有的,这些关键字会被 Qt 的 moc转换为标准的 C++语句。
假如我们单击窗口上的一个按钮后想要弹出一个对话框,那么可以将这个按钮的单击信号和自定义的槽关联起来,在这个槽中创建一个对话框并且显示它。这样,单击这个按钮时就会发射信号,进而执行和它关联的槽函数(处理这个信号)来显示一个对话框。
Qt 的部件类中有一些已经定义好了的信号和槽, 通常的作法是子类化部件类,然后添加自已的信号和槽。
QT/PyQt 使用的C++/Python语言虽然是面向对象的语言,但程序的具体实现代码仍然是由函数来实现的,因此所谓的对象之间的通信,从程序设计的角度来看,就是函数调用的问题,只不过是某个对象的成员函数调用另一个对象的成员函数而已。
从设计模式的角度来看,信号和槽其实就是观察者模式的一种实现,什么是观察者模式,可以参考GOF的设计模式一书。
Qt使用的信号和槽机制的基本思想如下:
信号和槽的执行大致过程如下:
定义一个信号:x
定义一个槽函数: void g(...){...} # g和h都是程序员定义的槽
另一个槽函数:void h(...){...}
关联信号和槽:(x, g) // 这一步是有程序员指定的
执行函数f时:
f(...)
{
做一些处理...
# 信号可以由程序员发射,也可以由系统发射,发射信号就相当于是一个函数调用
# 这里相当于调用函数g
发送信号: x
# 当接收信号的槽函数g执行完其自身的代码后,继续在这里往下运行
做另外一些处理...
}
需要注意的是:
Qt在其类库中已经预定义了很多信号和槽,因此在Qt中
# coding=utf-8
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QGridLayout
from PyQt5.QtCore import pyqtSignal, Qt
class MyWidget(QWidget):
# 申明一个自定义信号,带2个int类型的参数
btn_clicked_signal = pyqtSignal(int, int)
def __init__(self, parent=None):
super().__init__(parent)
self.init_ui()
def init_ui(self):
# 创建一个gridlayout用于网格布局
grid = QGridLayout()
grid.setSpacing(10)
# 创建一个label用于展示当前鼠标的位置坐标
x = y = 0
self.text = '左键点击窗口, 获取当前鼠标位置坐标 x:{0}, y:{1}'.format(x, y)
self.label = QLabel(self.text, self)
# 窗口布局
grid.addWidget(self.label, 0, 0, Qt.AlignmentFlag.AlignCenter)
self.setLayout(grid)
# 关联自定义信号和槽
self.btn_clicked_signal.connect(self.on_btn_click)
# 设置鼠标可追踪
self.setMouseTracking(True)
# 展示窗口
self.resize(200, 100)
self.setWindowTitle('自定义信号和槽示例程序')
self.show()
# 自定义的槽函数, 将获取到的鼠标坐标显示出来
def on_btn_click(self, x, y):
self.text = '左键点击窗口, 获取当前鼠标位置坐标 x:{0}, y:{1}'.format(x, y)
self.label.setText(self.text)
# 重写鼠标按下事件
def mousePressEvent(self, event):
if event.button() == Qt.MouseButton.LeftButton:
# 鼠标左键按下时,发射自定义信号
self.btn_clicked_signal.emit(event.x(), event.y())
if __name__ == '__main__':
app = QApplication(sys.argv)
my_widget = MyWidget()
my_widget.show()
sys.exit(app.exec_())
运行效果如下:
self.btn_clicked_signal.connect(self.on_btn_click)
self.btn_clicked_signal.emit(event.x(), event.y())
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。