QT信号槽
来源:互联网 发布:安卓新旧手机数据转移 编辑:程序博客网 时间:2024/06/09 06:05
信号槽是Qt框架引以为豪的机制之一。熟练使用和理解信号槽,能够设计出解耦的非常漂亮的程序,有利于增强我们的技术设计能力。
所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,用自己的一个函数(成为槽(slot))来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。我们来看一下信号槽的使用:
#include <QApplication>
#include <QPushButton>
int main(intargc, char *argv[])
{
QApplication app(argc, argv);
QPushButton button("quit");
QObject::connect(&button,SIGNAL(clicked()),&app,SLOT(quit()));
button.show();
returnapp.exec();
}
我们使用了SIGNAL和SLOT这两个宏,将两个函数名转换成了字符串。注意,即使quit()是QApplication的 static 函数,也必须传入一个对象指针。这也是信号槽语法的局限之处。另外,注意到connect()函数的 signal 和 slot 都是接受字符串,因此,不能将全局函数或者 Lambda 表达式(以后再说)传入connect()。一旦出现连接不成功的情况,Qt 4 是没有编译错误的(因为一切都是字符串,编译期是不检查字符串是否匹配),而是在运行时给出错误。这无疑会增加程序的不稳定性。
接下来看看三个不同的connect()重载:
bool connect(constQObject *, const char *,constQObject *, const char *,Qt::ConnectionType);
bool connect(constQObject *, const QMetaMethod &,constQObject *, const QMetaMethod &,Qt::ConnectionType);
bool connect(constQObject *, const char *,constchar *,Qt::ConnectionType)const
它们的返回值都是一样的,而且 signal 和 slot 只有const char *这么一种形式。
信号槽不是 GUI 模块提供的,而是 Qt 核心特性之一。因此,我们可以在普通的控制台程序使用信号槽。
那么自定义信号槽就必不可少了,自定义信号槽需要注意的事项:
1.发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
2.使用 signals 标记信号函数,信号是一个函数声明,返回 void,不需要实现函数代码;
3.槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
4.使用 emit 在恰当的位置发送信号;
5.使用QObject::connect()函数连接信号和槽。
下面给出相应例子的代码:
#include <QObject>
////////// newspaper.h
class Newspaper: public QObject
{
Q_OBJECT
public:
Newspaper(constQString & name):
m_name(name)
{
}
voidsend() const
{
emit newPaper(m_name);
}
signals:
voidnewPaper(const QString&name) const;
private:
QString m_name;
};
////////// reader.h
#include <QObject>
#include <QDebug>
class Reader: public QObject
{
Q_OBJECT
public:
Reader(){}
public slots:
voidreceiveNewspaper(const QString & name)const
{
qDebug()<< "Receives Newspaper: " << name;
}
};
////////// main.cpp
#include <QCoreApplication>
#include "newspaper.h"
#include "reader.h"
int main(intargc, char *argv[])
{
QCoreApplicationapp(argc, argv);
Newspaper newspaper("Newspaper A");
Reader reader;
QObject::connect(&newspaper,SIGNAL(newPaper(QString)),
&reader, SLOT(receiveNewspaper(QString)));
newspaper.send();
returnapp.exec();
}
main()函数中,QObject::connect()函数,第二、第四个参数需要使用SIGNAL和SLOT这两个宏转换成字符串(具体事宜我们在上一节介绍过)。注意SIGNAL和SLOT的宏参数并不是取函数指针,而是除去返回值的函数声明,并且 const 这种参数修饰符是忽略不计的。
我们提到了“槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响”,public、private 这些修饰符是供编译器在编译期检查的,因此其影响在于编译期。其连接是在运行时完成的,因此即便是 private 的槽函数也是可以作为槽进行连接的。
0 0
- Qt 信号与信号,信号与槽
- QT---QT的信号槽
- qt 槽与信号
- QT信号与槽
- Qt信号和槽
- QT 信号与槽
- QT信号和槽
- QT信号槽
- QT信号和槽
- QT信号与槽
- Qt信号与槽
- QT信号槽
- QT 信号和槽
- Qt ---- 信号和槽
- Qt 之 信号槽
- Qt信号与槽
- QT信号和槽
- QT信号与槽
- 四月,不曾走远
- PHP面试心得(不涉及技术)
- <Oracle 数据库内存结构 请读者多多指教>
- 观察者模式--lua实现
- HDOJ1232 畅通工程 【并查集】
- QT信号槽
- jsp中的window.open和window.showModalDialog的弹出页面以及传参
- 大型系统架构演化
- 原型模式(深拷贝)
- poj Catenyms
- ARC和非ARC模式
- 嵌入式--Nand Flash存储
- Android调试出现Source not found解决办法
- 第六章 Linux内核的Softirq机制