之前写按钮的信号槽,都是直接转到槽的。昨天在写计网课设的时候,自己写了一个信号槽,于是就记录一下。
声明:本章大部分内容及思想均来自于博客:C++面试题之 QT信号和槽实现机制
一、信号与槽机制基本介绍
所谓信号槽,实际就是观察者模式。
当某个事件发生之后(比如button
检测到自己被点击了一下),它可以利用emit
发出一个信号signal
。此时的发送是没有目的的,可以理解为广播信号。
如果有对象对这个signal
感兴趣(比如说这个对象需要在这个事件发生时,进行某些操作),它就可以定义一个槽slot
,并用connect
函数与signal
进行绑定。
绑定后,当信号发出时,被连接的槽函数会自动被回调。
1. 槽函数
槽函数本质是类成员函数,唯一的区别就是:槽函数slot
可以与信号signal
连接在一起。
2. 说明
(1)只有继承了QObject
类的类,才具有信号槽的能力
凡是QObject
类或其子类,都需要在类定义的第一行加上语句Q_OBJECT
。比如:
(2)信号函数的参数类型必须与槽函数的参数类型一致,且个数必须大于等于槽函数的参数个数
(3)connect
函数用法
在进行的地方写如下语句:
QObeject::connect(<sender>, <&Send::signal>, <receiver>, <&Receiver::slot>);
其中,
sender
:发送方指针,即发生事件的对象的指针&Send::signal
:发送方的信号函数signal
receiver
:接收方指针,即对发送方信号感兴趣的对象的指针&Receiver::slot
:接收方的槽函数slot
图示:
二、举例说明
在本次计网课设中,我需要实现的功能是:一个线程在启动之后,会输出一些信息到界面上。
1. 分析
sender
:该线程可以看成sender
类&Send::signal
:“线程将信息广播发送出去”这个事件可以看成是signal
receiver
:界面可以看成receiver
类&Receive::slot
:将信息输出到界面可以看成是slot
2. 实现
假设sender
类、receiver
类分别为MyThread
、ReceiveWindow
(1)发送方头文件:mythread.h
(2)发送方源文件:mythread.cpp
线程启动之后,会自动调用run()
函数。所以需要在run()
中通过emit
发出信号。下面只给出部分代码
void MyThread::run()
{
...
QString info = "-------------- The information of Packet " + QString::number( ++ cnt, 10) + " --------------";
emit sendMessage(info); // 此时,就会发送信号
}
(3)接收方头文件:receivewindow.h
(4)接收方源文件:receivewindow.cpp