QT5:信号与槽
一.元对象
QT使用元对象编译器(Meta Object Compiler,moc),实现了元对象(Meta Object System,mos)机制,为标准C++增加了一些特性:
信号槽机制,用于解决对象之间的通讯
可查询可设计的对象属性
强大的事件机制以及事件过滤器
基于上下文的字符串翻译机制(国际化),用 tr() 函数实现
复杂的定时器实现,用于在事件驱动的GUI中嵌入能够精确控制的任务集成
层次化的可查询的对象树,提供一种自然的方式管理对象关系
智能指针(QPoint),在对象析构之后自动设为0,防止野指针
能够跨越库边界的动态转换机制
元对象系统是基于以下3个条件: (1)基类QObject:任何需要使用元对象系统功能的类必须继承自QObject类 (2)Q_OBJECT宏:必须在类的私有声明区声明Q_OBJECT宏(默认为private) (3)元对象编译器(Meta-Object Compiler,moc):为QObject子类实现元对象特性提供必要的代码
二.信号槽
QT编程中信号与槽用于处理界面各个组件的交互,类似与MFC的消息循环和绑定
注意:在使用信号与槽的类中,必须在类的定义中加入宏定义Q_OBJECT
信号(Signal)就是在特定情况下被发射的时间,类似于鼠标单击时发生clicked()信号
槽(Slot)是对信号响应的函数
QT中的信号(Signals)和槽(Slot)的机制进行通信,需要继承QObject基类,继承这个基类就会生成一个moc文件,没有这个文件就不能使用信号和槽
1.转到槽
在需要设计槽的控件(触发控件)上右键->转到槽 或者直接按下F4进入快速选择信号和槽函数 选择相应的信号之后就会跳转到该信号函数 lineEdit 文本编辑框 textChanged(QString) testEdited(QString) pushButton 按钮 clicked() clicked(bool) pressed()
QTCreator会把该控件的信号自动生成对应的槽函数,QT会自动识别相关的槽函数,但是注意这里槽函数的名字是一一对应的,并不能自定义改动
//helloDialog.h class HelloDialog : public QMainWindow { // 声明槽函数 private slots: void on_pushButton_clicked(); }
//helloDialog.cpp void HelloDialog::on_pushButton_clicked() { ui->lineEdit->setText("k5"); }
2.Connect信号槽
connect(
ui文件下的控件名称
控件自带的信号函数
自定义的对象
自定义的槽函数
)
//helloDialog.h class HelloDialog{ public: void initSignalSlots(); //初始化信号与槽连接 <br>// 声明槽函数 private slots: void changeData(); }
//helloDialog.cpp void HelloDialog::initSignalSlots() { connect(ui->pushButton,SIGNAL(cliked()),this,SLOT(changeData)); } void HelloDialog::changeData(){ ui->lineEdit->setText("k5"); }
QT4使用宏 SIGNAL()和SLOT()来声明信号与槽 connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close())); QT5使用指针地址来表示,可以进行编译时的类型检查(要考虑函数指针重载) conenct(ui->pushButton, &QPushButton::clicked, this, &MainWindow::close);
3.自定义信号与槽
除了使用QT内置的信号函数和槽函数,也可以自定义信号和槽函数.
创建两个类继承QObject类,添加Q_Object宏,用signals和slots标记信号和槽函数
信号需要声明不需要实现,槽需要声明也需要实现。信号槽都不需要返回值,可以有参数,可以重载
注意:使用 signals 标记信号函数,信号是一个函数声明,返回void,不需要实现函数代码
使用 emit 可以发送信号
// test.h #ifndef TEST_H #define TEST_H #include <QObject> #include <QDebug> class test : public QObject { Q_OBJECT public: test(); void send(){ emit testcall(); } signals: void testcall(); public slots: void testreveive(); } #endif // TEST_H
// test.cpp<br><br>#include "test.h" test::test() { } void test::testreceive(){ qDebug() << "receive"; }
// mainwindow.cpp #include "ui_mainwindow.h" #include "test.h" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) { test t; connect(&t, &test::testcall, &t, &test::testreceive); t.send(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)