Qt学习之路(9):深入了解信号槽

简介:
信号槽机制是Qt编程的基础。通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯。这就将类之间的关系做了最大程度的解耦。
 
槽函数和普通的C++成员函数没有很大的区别。它们也可以使virtual的;可以被重写;可以使public、protected或者private的;可以由其它的C++函数调用;参数可以是任何类型的。如果要说区别,那就是,槽函数可以和一个信号相连接,当这个信号发生时,它可以被自动调用。
 
connect()语句的原型类似于:
 
connect(sender, SIGNAL(signal), receiver, SLOT(slot));
 
这里,sender和receiver都是QObject类型的,singal和slot都是没有参数名称的函数签名。SINGAL()和SLOT()宏用于把参数转换成字符串。
 
深入的说,信号槽还有更多可能的用法,如下所示。
 
一个信号可以和多个槽相连:
 
connect(slider, SIGNAL(valueChanged( int)),
              spinBox, SLOT(setValue( int))); 
connect(slider, SIGNAL(valueChanged( int)),
               this, SLOT(updateStatusBarIndicator( int)));
 
注意,如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。
 
多个信号可以连接到一个槽:
 
connect(lcd, SIGNAL(overflow()),
               this, SLOT(handleMathError())); 
connect(calculator, SIGNAL(divisionByZero()),
               this, SLOT(handleMathError()));
 
这是说,只要任意一个信号发出,这个槽就会被调用。
 
一个信号可以连接到另外的一个信号:
 
connect(lineEdit, SIGNAL(textChanged( const QString &)),
               this, SIGNAL(updateRecord( const QString &)));
 
这是说,当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。
 
槽可以被取消链接:
 
disconnect(lcd, SIGNAL(overflow()),
                  this, SLOT(handleMathError()));
 
这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。
 
为了正确的连接信号槽,信号和槽的参数个数、类型以及出现的顺序都必须相同,例如:
 
connect(ftp, SIGNAL(rawCommandReply( intconst QString &)),
               this, SLOT(processReply( intconst QString &)));
 
这里有一种例外情况,如果信号的参数多于槽的参数,那么这个参数之后的那些参数都会被忽略掉,例如:
 
connect(ftp, SIGNAL(rawCommandReply( intconst QString &)), 
             this, SLOT(checkErrorCode( int)));
 
这里,const QString &这个参数就会被槽忽略掉。
 
如果信号槽的参数不相容,或者是信号或槽有一个不存在,或者在信号槽的连接中出现了参数名字,在Debug模式下编译的时候,Qt都会很智能的给出警告。
 
在这之前,我们仅仅在widgets中使用到了信号槽,但是,注意到connect()函数其实是在QObject中实现的,并不局限于GUI,因此,只要我们继承QObject类,就可以使用信号槽机制了:
 
class Employee :  public QObject 

        Q_OBJECT  
public
        Employee() { mySalary = 0; }   
         int salary()  const {  return mySalary; } 
 
public slots: 
         void setSalary( int newSalary); 
 
signals: 
         void salaryChanged( int newSalary); 
 
private
         int mySalary; 
};
 
在使用时,我们给出下面的代码:
 
void Employee::setSalary( int newSalary) 

         if (newSalary != mySalary) { 
                mySalary = newSalary; 
                emit salaryChanged(mySalary); 
        } 
}
 
这样,当setSalary()调用的时候,就会发出salaryChanged()信号。注意这里的if判断,这是避免递归的方式!还记得前面提到的循环连接吗?如果没有if,当出现了循环连接的时候就会产生无限递归。


本文转自 FinderCheng 51CTO博客,原文链接:
http://blog.51cto.com/devbean/199461
相关文章
|
6月前
Qt第二课 核心机制信号槽
Qt第二课 核心机制信号槽
68 1
|
6月前
|
存储 API C++
【Qt 信号槽】深入探索 Qt 信号和槽机制中的引用传递“ (“A Deep Dive into Reference Passing in Qt Signal and Slot Mechanism“)
【Qt 信号槽】深入探索 Qt 信号和槽机制中的引用传递“ (“A Deep Dive into Reference Passing in Qt Signal and Slot Mechanism“)
496 0
|
2月前
|
定位技术 Go 开发工具
dynamic-situational-awareness-qt学习记录
本文是作者yantuguiguziPGJ关于dynamic-situational-awareness-qt学习记录的分享,介绍了在Qt学习过程中发现的qml资源丰富的代码仓库,并提供了资源路径和相关的安装、配置步骤,涉及的内容有数字地球、GIS纹理等,同时提供了相关链接和git命令来克隆代码仓库和ArcGIS Runtime SDK for Qt的安装说明。
|
6月前
【qt】核心机制信号槽(下)
【qt】核心机制信号槽(下)
38 1
|
6月前
|
消息中间件 存储 安全
深入理解 Qt 信号槽:高效沟通的桥梁
深入理解 Qt 信号槽:高效沟通的桥梁
737 1
|
3月前
QT信号槽
QT信号槽
35 0
|
4月前
|
C++
Qt中的信号与槽如何学习?(包括自定义信号)这篇文章告诉你
以现实中的事件来举例的话,例如有两把不同颜色的信号枪,分别是红色,绿色,打响不通颜色的信号枪会触发不同的槽发生,比如说打响红色这个人就跑步,绿色就走步,但是还有一个很重要的机制,那就是连接,我们需要把信号枪去跟这个人的动作连接起来。 如果上面理解没问题的话我们可以把信号和槽看成两个工具,我们最重要的是如何去把这两个工具连接起来。 它的作用可以让我们更加灵活的去使用不同窗口间的切换以及某些事件的连接。
|
4月前
|
开发者
Qt中的事件该如何学习?(附带案例)
事件是Qt中比较重要的一部分,在初期如果理解不当学习可能会比较困难,这里提一嘴当初教我的那位老师水平是真的高,让我很轻易的就理解了事件的概念。 在平时我们见到那些界面上的某些快捷键就有可能是事件做的,例如ESC关闭窗口,Enter提交或者登录这种类似的,这也是事件的强大之处。
|
5月前
|
编译器
(16):深入 Qt5 信号槽新语法
(16):深入 Qt5 信号槽新语法
|
5月前
Qt 信号槽(笔记)
Qt 信号槽(笔记)