Qt信号与槽机(1)
Qt 采用事件驱动的编程模型用户对界面做的每一次操作都会触发事件框架随之发出信号控件再对信号做出响应。信号与槽正是这套流程里的消息传输机制它让相互独立的控件得以协作也是理解 Qt 程序结构的一条主线。这篇内容按一条主线展开先建立对信号与槽的概念认知再掌握连接与内置信号槽的用法编写自定义信号槽并处理带参与重载的情况梳理常见的几种连接关系最后补充断开、Qt4 写法与 Lambda 槽函数等进阶用法。一、基础认知1.1 事件、信号与槽在 Qt 中用户和控件的每次交互过程都是一个事件。点击按钮是事件关闭窗口也是事件。每个事件都会产生一个信号比如按钮被点击时发出“按钮被点击”的信号窗口关闭时发出“窗口被关闭”的信号。信号与槽能把相互独立的控件关联起来。按钮和窗口原本互不影响点击按钮并不会对窗口造成影响借助信号与槽机制就能实现“点击按钮使窗口关闭”的效果。1.2本质信号的本质是事件。用户对窗口或控件执行了某些操作触发特定事件后Qt 对应的窗口类就会发出某个信号来回应这次操作。比如按钮的单击、双击窗口的刷新鼠标的移动、按下、释放键盘的输入都属于能被框架捕捉的事件。对哪个窗口进行操作哪个窗口就能捕捉到这些事件。槽的本质是对信号响应的函数。槽函数和普通 C 函数没有本质差别可以定义在类的各个访问区域可以带任意参数可以被重载也可以被直接调用只是不能有默认参数。实现层面有两点值得留意。1信号和槽机制底层是函数间的相互调用。每个信号都能用函数表示每个槽也能用函数表示。2信号函数和槽函数通常位于某个类中与普通成员函数相比特别之处在于信号函数用 signals 关键字修饰槽函数用 public slots、protected slots 或 private slots 修饰signals 和 slots 是 Qt 在 C 基础上扩展的关键字。connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type Qt::AutoConnection);对比项信号函数槽函数关键字signalspublic slots / protected slots / private slots声明与定义只需要声明声明与实现都需要函数体由 Qt 自动生成由开发者编写触发方式事件触发、emit 发射关联信号后自动执行也可直接调用默认参数—不能有默认参数二、基本使用2.1 连接信号和槽在 Qt 中QObject 类提供了一个静态成员函数 connect()专门用来把指定的信号函数和槽函数关联起来。QObject 是 Qt 内置的父类Qt 提供的很多类都直接或间接继承自它这一点和 Java 的继承体系比较相似。connect() 的函数原型参数含义sender信号的发送者signal发送的信号receiver信号的接收者method接收信号的槽函数type关联方式默认 Qt::AutoConnection拿“在窗口中设置一个按钮点击按钮关闭窗口”来示范#include widget.h #include QPushButton Widget::Widget(QWidget *parent) : QWidget(parent) { QPushButton *btn new QPushButton(关闭窗口, this); // 创建按钮 resize(800, 600); // 调整窗口大小 // 关联信号和槽点击“按钮”关闭“窗口” connect(btn, QPushButton::clicked, this, QWidget::close); } Widget::~Widget() { }2.2 查看内置信号和槽系统自带的信号和槽通常通过 Qt 的帮助系统来查询。以查询按钮的信号为例输入 QPushButton 后按下面的顺序找在 Contents 中寻找关键字 signals没有找到时继续去父类 QAbstractButton 中查找 signals在列出的信号中找到 clicked()QAbstractButton 里的信号主要有这几个信号触发时机void clicked(bool checked false)按钮被点击时发出void pressed()按钮被按下时发出void released()按钮被释放时发出void toggled(bool checked)按钮状态切换时发出槽函数的查找方式与信号一致只是关键字换成 slot。2.3 借助 Qt Creator 生成信号槽代码Qt Creator 可以快速帮助生成信号槽相关的代码。目标还是实现“点击按钮关闭窗口”操作分成几个环节1新建项目并保留 UI 设计文件新建项目时注意勾选生成 UI 设计文件完成后项目里会多出一个 widget.ui 文件。2进入 UI 设计界面双击 widget.ui 文件进入设计模式左侧是控件工具箱中间是设计画布右侧是属性面板与对象列表。3拖入按钮并修改属性从控件工具箱的 Buttons 分组中把 Push Button 拖到画布上再修改按钮的名称objectName、文本及字体大小等属性。4可视化生成槽函数先选中按钮组件点击鼠标右键在弹出的菜单中单击“转到槽…”。对按钮来说点击时发送的信号是 clicked()因此在弹出的对话框中选择 clicked()。普通按钮使用 clicked 信号即可clicked(bool) 对普通按钮没有实际意义具有特殊状态的按钮比如复选按钮才会用到 clicked(bool)。5自动生成槽函数原型框架选择信号后Qt Creator 会自动生成槽函数的原型框架在 widget.h 头文件中添加槽函数声明在 widget.cpp 中生成槽函数定义。6补充槽函数的功能代码在自动生成的槽函数定义中添加要实现的功能这里写入 this-close()实现关闭窗口的效果。2.4 自动生成槽函数的命名规则自动生成的槽函数遵循 on_XXX_SSS 的命名规则以 on 开头中间用下划线连接起来XXX 表示对象名SSS 表示对应的信号例如 on_pushButton_clicked()pushButton 是对象名clicked 是对应的信号。按照这种命名风格定义的槽函数会被 Qt 自动与对应的信号连接。日常写代码时除非是 IDE 自动生成否则建议显式使用 connect而不是依赖命名规则。显式 connect 一方面能更清晰直观地描述信号和槽的连接关系另一方面也能避免信号或槽名字拼写错误导致连接失效。至于配置大于约定还是约定大于配置业界尚有争议这里更推荐优先考虑显式 connect。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →