Qt 信号和槽函数
信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性。当某个信号被发射,就需要调用与之相绑定的槽函数。这与Windows下的消息机制类似,消息机制是基于回调函数。一个回调即是一个函数的指针,因此如果希望一个处理函数通知一些事件,可以传递一个函数(回调函数)的指针给这个处理函数。这个处理函数就会在适当的时候调用回调函数。但是回调函数有两大缺点:第一,它们不是类型安全的。我们从来不敢确定处理函数会用正确的参数来调用回调函数;第二,回调函数被强力和处理函数联系着,因为处理函数必须知道去调用哪个回调函数。
信号和槽的机制是类型安全的:一个信号的签名必须与接收槽的签名相匹配。(实际上一个槽可能有一个比它所接收到的信号的签名更短的签名因为它能够忽略额外的参数。)因为签名是一致的,所以编译器能够帮助我们发现类型不匹配。信号和槽是松散的联系在一起的:一个发射信号的类从来不知道也不关心哪个槽接收这个信号。Qt的信号和槽机制确保如果你将一个信号和一个槽连接起来,这个槽将在正确的时间被用这个信号的参数所调用。信号和槽可以带任何数量任何类型的参数。它们完全是类型安全的。
信号(Signals)
当对象改变其状态时,信号就由该对象发射 (emit) 出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号。这样就做到了真正的信息封装,能确保对象被当作一个真正的软件组件来使用。
信号只需要在头文件中进行声明,不需要在cpp中实现。放在Qt自定义关键字signals下,在此之前一定要加上Q_OBJECT宏。
在编程中,一般使用的是控件内部定义好的信号。如:QTreeWidget类下的 Signals:
void currentItemChanged ( QTreeWidgetItem * current, QTreeWidgetItem * previous );
void itemActivated ( QTreeWidgetItem * item, int column );
void itemChanged ( QTreeWidgetItem * item, int column );
void itemClicked ( QTreeWidgetItem * item, int column );
void itemCollapsed ( QTreeWidgetItem * item );
void itemDoubleClicked ( QTreeWidgetItem * item, int column );
void itemEntered ( QTreeWidgetItem * item, int column );
void itemExpanded ( QTreeWidgetItem * item );
void itemPressed ( QTreeWidgetItem * item, int column );
void itemSelectionChanged ();
也可以自定义信号,并通过emit在代码中发射信号。
class sender : public QObject
{
Q_OBJECT public:
void doSend();
signals:
void send(int);
};
// ------------ sender.cpp -----------
#include "sender.h"
void sender :: doSend()
{
emit send();
}
槽函数(Slots)
槽和普通的C++成员函数几乎是一样的(可以是虚函数,可以被重载,可以是public slots、protected slots、private slots,可以被其他C++成员函数直接调用;唯一不同的是:槽还可以和信号连接在一起,在这种情况下,信号被发射时,会自动调用这个槽。)槽不需要信号传过来的参数时,可以不要参数;但槽一旦要参数,其参数个数,类型,顺序必须要和对应的信号保持一致。另外,槽的参数不能有缺省值。
class receiver : public QObject
{
Q_OBJECT public slots:
//带有参数的槽函数,需和绑定的信号的参数保持一致
void recv(int);
};
// ------------ Receiver.cpp -----------
void receiver :: recv(int n)
{
qDebug()<<"recv number: "<<n<<endl;
}
关联信号和槽(connect)
可以使用QObject类的静态成员函数connect来建立信号的槽的关联
bool QObject::connect (const QObject * sender, const char * signal, const QObject * receiver, const char * slot) [static]
具体的调用为:connect(sender, SIGNAL(signal), receiver, SLOT(slot)); 其中sender和receiver为QObject类对象的指针; SIGNAL宏和SLOT宏将信号的槽转换成字符串。
sender s;
receiver r;
QObject::connect(&s, SIGNAL(send(int)), &r, SLOT(recv(int)));
注:在connect函数中信号函数和槽函数若有参数,只能写出参数类型,而不能也将变量名写出;否则,连接会失败!
- 一个信号可以连接多个槽
当信号发射时,会以不确定的顺序一个接一个的调用各个槽。
- 多个信号可以连接同一个槽
即无论是哪一个信号被发射,都会调用这个槽。
- 信号直接可以相互连接
发射第一个信号时,也会发射第二个信号。
断开信号和槽(disconnect)
当信号和槽没有必要继续保持连接时,可以通过调用disconnect来断开它们。
bool QObject::disconnect (const QObject * sender, const char * signal, const Object * receiver, const char * slot) [static]
有三种情况必须使用 disconnect() 函数:
(1)断开与某个对象相关联的任何对象。
disconnect(sender, , , ) ;
//或者
sender->disconnect();
(2)断开与某个特定信号的任何关联。
disconnect(sender, SIGNAL(signal()), , );
//或者
sender->disconnect(SIGNAL(signal()));
(3)断开两个对象之间的关联。
disconnect(sender, , receiver, );
//或者
sender->disconnect(receiver);
应注意的问题
- 信号与槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时也有可能产生死循环。因此,在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样信号。例如 , 在前面给出的例子中如果在 mySlot() 槽函数中加上语句 emit mySignal() 即可形成死循环。
- 如果一个信号与多个槽相联系的话,那么,当这个信号被发射时,与之相关的槽被激活的顺序将是随机的。
- 宏定义不能用在 signal 和 slot 的参数中。
- 信号和槽的参数个数与类型必须一致。
Qt 信号和槽函数的更多相关文章
- QT信号和槽函数学习笔记
//connect 函数有4个参数 分别是 发送者 信号.接受者 ,槽 //connect(sender,signal,receiver,slot) /* * 信号和槽 * 信号 就是一个普通的函数 ...
- QT+信号和槽函数_自定义槽函数_一个信号对应多个槽函数
以下的代码里面有自定义槽函数的内容,同时也有信号实现的函数: #ifndef MAINWIDGET_H #define MAINWIDGET_H #include <QWidget> #i ...
- qt的信号与槽函数
关联: bool connect ( const?QObject?*?sender, const?char?*?signal, const QObject * receiver, const char ...
- 【QT】无需写connect代码关联信号和槽函数
对于一些简单的事件判别,如点击按钮. 无需写代码关联信号和槽函数. connect(ui->Btnshowhello,SIGNAL(clicked(bool)),this,SLOT(Btnsho ...
- Qt之自定义信号和槽函数
自定义信号和槽函数: 1.类的声明和实现分别放在.h和.cpp文件中: 2.类声明包含Q_OBJECT宏: 3.信号只要声明不要设计其的实现函数 4.发射信号用emit关键字 5.自定义槽的实现与普通 ...
- QT 信号与槽connect
QT 信号与槽connect QT 信号与槽connect connect函数调用几个限制 connect函数代码 QT中信号与槽的连接使用的connect函数是一个静态函数,在类QObject中定义 ...
- QT 信号与槽连接
转帖 http://www.cnblogs.com/cnhome/archive/2009/10/01/1577277.html 信号(SIGNAL)和槽(SLOT)是Qt编程的一个重要部分.这个机制 ...
- Qt 信号与槽
Qt信号与槽的理解 信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解.信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重 ...
- QT 信号与槽 QT简单加法器的实现
信号与槽 背景: 面向过程 模块之间低耦合设计(高内聚). 函数调用: 直接调用 回调调用(低耦合) 面向对象 模块之间低耦合设计(高内聚) 对象调用 直接调用 接口调用 QT: 信号与槽解决问题: ...
随机推荐
- DBA_Oracle PFile and SPFile文件的管理和使用(案例)
2014-08-25 Created By BaoXinjian
- Codeforces Round #363 (Div. 2) One Bomb
One Bomb 题意: 只有一个炸弹,并且一个只能炸一行和一列的'*',问最后能否炸完所以'*',如果可以输出炸弹坐标 题解: 这题做的时候真的没什么好想法,明知道b题应该不难,但只会瞎写,最后越写 ...
- poj_2485_mst
Highways Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit St ...
- curl命令使用小结[转]
curl命令有不少小技巧,linux下测试确实很方便.转http://blog.csdn.net/zhangliang_571/article/details/26379777 1.开启gzip请求c ...
- JAVA 子父类的特点
一.变量(属性) this 代表当前对象的引用 this.变量 首先在本类中找所需要的这个变量,如果没有找到再去父类中找 super 用于访问当前对象的父类成员 super.变量 直接在父 ...
- 定时任务 Crontab命令 详解
crontab是Unix和Linux用于设置周期性被执行的指令,是互联网很常用的技术,很多任务都会设置在crontab循环执行,如果不使用 crontab,那么任务就是常驻程序,这对你的程序要求比较高 ...
- java异常处理机制throws
throws可以在方法声明时抛出的异常.原则上throws声明的异常,一定要在该方法中抛出,否则没有意义. 相反的,若方法中我们主动通过throw抛出一个异常,应该在throws中声明该种类异常,通知 ...
- Codeforces 452D [模拟][贪心]
题意: 给你k件衣服处理,告诉你洗衣机烘干机折叠机的数量,和它们处理一件衣服的时间,要求一件衣服在洗完之后必须立刻烘干,烘干之后必须立刻折叠,问所需的最小时间. 思路: 1.按照时间模拟 2.若洗完的 ...
- sencha touch 开发准备
这是本人第一次写博客教程,没什么经验,文笔也不是很好,写这教程一方面为了巩固自己这段时间的学习成果,一方面帮助大家解决问题,欢迎大家多提建议,指出问题.接下来我们就开始我们的sencha touch开 ...
- SQL执行的原理以及一些常见的关键字
sql语句在面试里面问道的问题: sql的解析的顺序 1.where里面的条件是从右向左扫描解析 2.from里面的大表在前,小表在后,解析的顺序是从右向左解析. 3.left/right/inner ...