Signal 和Slot 机制

简介: 在Qt中,有一种用于对象之间的通信:信号-槽机制,这种机制是Qt的核心机制,也是它区别于其他GUI工具的最主要的特征。信号-槽机制可以携带任意类型、任意数量的参数,而且完全是安全的,不会引起系统的崩溃。

Qt中,有一种用于对象之间的通信:信号-槽机制,这种机制是Qt的核心机制,也是它区别于其他GUI工具的最主要的特征。信号-槽机制可以携带任意类型、任意数量的参数,而且完全是安全的,不会引起系统的崩溃。用户可以按照需要将许多信号与一个单独的槽函数相联系,一个信号也可以按需要被联系到很多不同的槽函数。甚至还可以将一个信号直接与另一个信号相联系,这样当第一个信号被发出时立刻发出第二个信号。

当某个信号所对应的客户或其所有者的内部状态发生改变时,信号被一个对象发射。只有定义过这个信号的类及其派生类能够发射这个信号。当一个信号被发射时,与其相关联的

槽将被立刻执行,就象调用一个正常的函数一样。信号-槽机制完全独立于任何GUI事件循环。只有当所有的槽返回以后发射函数(emit)才返回。如果存在多个槽与某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地执行,但是它们执行的顺序将会是随机的、不确定的,我们不能人为地指定哪个先执行、哪个后执行。例如,一个列表框可以发出highlighted()activated()的信号,大多数对象也许只对activated()的信号感兴趣,但也许

有些对象需要知道该列表框中的哪一项被选中了。如果有两个不同的对象对一个信号感兴趣,只要将该信号连接到这两个对象的槽上就可以了。

Signal和Slot的声明

Qt程序设计中,凡是包含signalslot的类中都要加上Q_OBJECT的定义,下面的例子给出了如何在一个类中定义signalslot

class Student : public QObject

{

Q_OBJECT

public:

Student() { myMark = 0; }

int mark() const { return myMark; }

public slots:

void setMark(int newMark);

signals:

void markChanged(int newMark);

private:

int myMark;

};

signalslot在类体内通常声明为void型成员函数,允许带参数signal 不需要实体,slot必须要有实体,否则错误就同声明一个函数却没有实体一样,会发生链接错误

signal的发出一般在事件的处理函数中,利用emit发出signal,在下面的例子中在在事件处理结束后发出signal

void Student::setMark(int newMark)

{

if (newMark!= myMark) {

myMark = newMark;

emit markChanged(myMark);

}

}

Signal和Slot的连接

signalslot声明以后,需要使用connect()函数将它们连接起来。connect()函数属于QObject类的成员函数,它能够连接signalslot,也可以用来连接signalsignal函数原形如下:

bool connect ( const QObject * sender, const char * signal,const char * member ) const

其中第一个和第三个参数分别指出signalslot是属于那个对象或组件

在使用connect()函数进行来接的时候,还需要用到SIGNAL()SLOT()这两个宏,使用方法如下:

QLabel *label = new QLabel;

QScrollBar *scroll = new QScrollBar;

QObject::connect( scroll,SIGNAL(valueChanged(int)),label, SLOT(setNum(int)) );

同一个信号连接多个插槽

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()));

取消一个连接不是很常用,因为Qt会在一个对象被删除后自动取消这个对象所包含的所有的连接

相关文章
|
设计模式 Unix Shell
ECF机制:信号 (Signal)
ECF机制:信号 (Signal)
189 0
|
2月前
|
存储 JavaScript 前端开发
深入理解JavaScript中的事件循环(Event Loop):机制与实现
【10月更文挑战第12天】深入理解JavaScript中的事件循环(Event Loop):机制与实现
87 3
|
7月前
|
消息中间件 Unix Linux
【ZMQ polling机制】ZMQ异步接收机制以及与epoll/select的对比分析
【ZMQ polling机制】ZMQ异步接收机制以及与epoll/select的对比分析
468 0
|
JavaScript
说说你对slot的理解?slot使用场景有哪些?
说说你对slot的理解?slot使用场景有哪些?
155 1
|
JavaScript 容器
如何理解slot?slot使用场景有哪些?
如何理解slot?slot使用场景有哪些?
128 0
|
存储 固态存储 Linux
深入学习tombstone和signal
深入学习tombstone和signal
深入学习tombstone和signal
|
消息中间件 调度
RT-Thread记录(六、IPC机制之信号量、互斥量和事件集)
上文说到 RT-Thread 对临界区的处理方式有多种,其中已经分析了关闭调度器和屏蔽中断的方式, 本文就来学学另外的线程同步方式。
732 0
RT-Thread记录(六、IPC机制之信号量、互斥量和事件集)