说到QT,不得不提QT的信号与槽。
信号和槽机制是Qt的核心机制之一,要掌握Qt编程就需要对信号和槽有所了解。信号和槽是一种高级接口,它们被应用于对象之间的通信,它们是Qt的核心特性,也是Qt不同于其它同类工具包的重要地方之一。在我们所了解的其它GUI工具包中,窗口小部件(widget)都有一个回调函数用于响应它们触发的动作,这个回调函数通常是一个指向某个函数的指针。在Qt中用信号和槽取代了上述机制。
连接信号与槽是connect()函数,原型如下:
bool QObject::connect ( const QObject * sender, const QMetaMethod & signal, const QObject * receiver, const QMetaMethod & method, Qt::ConnectionType type = Qt::AutoConnection ) [static]
它可以把一个对象(sender)发送的信号(signal)和接收者(receiver)的槽函数(method)关联起来,这样当信号产生时与之关联的槽函数就会被执行。在connect函数里面我们用到了Qt提供的两个宏SIGNAL()和SLOT();在实际的开发中,信号和槽的使用非常多。而且灵活性也比较高。
先来一个简单的应用吧,信号和槽来实现对象之间的通信
在这个过程中,一个对象跟另个个对象实现通信,这儿我写一个专门来进行信号传递的对象,这个对象只进行信号传递。为了保证这个对象的唯一性,这儿引入了单例模式。下面的例子来实现信号传递,为后面的多线程之间的通信做铺垫。
下面是代码部分
doaction.h
#ifndef DOACTION_H
#define DOACTION_H
#include <QObject>
#include "sigtransport.h"
class DoAction : public QObject
{
Q_OBJECT
public:
explicit DoAction(QObject *parent = 0);
signals:
void SigDo();
void SigValue(int value);
void SigString(QString &);
public slots:
void SigDoSlot();
void SigValueSlot(int value);
void SigStringSlot(QString &);
};
#endif // DOACTION_H
doservice.h
#ifndef DOSERVICE_H
#define DOSERVICE_H
#include <QObject>
class DoService : public QObject
{
Q_OBJECT
public:
explicit DoService(QObject *parent = 0);
signals:
void SigDo();
void SigValue(int value);
void SigString(QString &);
public slots:
void SigDoSlot();
void SigValueSlot(int value);
void SigStringSlot(QString &);
};
#endif // DOSERVICE_H
sigtransport.h
#ifndef SIGTRANSPORT_H
#define SIGTRANSPORT_H
#include <QObject>
class SigTranSport : public QObject
{
Q_OBJECT
public:
explicit SigTranSport(QObject *parent = 0);
static SigTranSport *m_instance;
static SigTranSport *Instance();
signals:
void DaSigDo();
void DaSigValue(int value);
void DaSigString(QString &);
void DsSigDo();
void DsSigValue(int value);
void DsSigString(QString &);
public slots:
};
#endif // SIGTRANSPORT_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
:QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(SigTranSport::Instance(),SIGNAL(DsSigDo()),&ds,SIGNAL(SigDo()));
connect(SigTranSport::Instance(),SIGNAL(DsSigValue(int)),&ds,SIGNAL(SigValue(int)));
connect(SigTranSport::Instance(),SIGNAL(DsSigString(QString &)),&ds,SIGNAL(SigString(QString &)));
connect(SigTranSport::Instance(),SIGNAL(DaSigDo()),&da,SIGNAL(SigDo()));
connect(SigTranSport::Instance(),SIGNAL(DaSigValue(int)),&da,SIGNAL(SigValue(int)));
connect(SigTranSport::Instance(),SIGNAL(DaSigString(QString &)),&da,SIGNAL(SigString(QString &)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_DaBtn_clicked()
{
static int num = 0;
QString str;
str.sprintf("num : is %d",++ num);
emit SigTranSport::Instance()->DaSigDo();
emit SigTranSport::Instance()->DaSigValue(num);
emit SigTranSport::Instance()->DaSigString(str);
qDebug() << "da is send ...";
}
void Widget::on_DsBtn_clicked()
{
static int num = 0;
QString str;
str.sprintf("num : is %d",++ num);
emit SigTranSport::Instance()->DsSigDo();
emit SigTranSport::Instance()->DsSigValue(num);
emit SigTranSport::Instance()->DsSigString(str);
qDebug() << "ds is send ...";
}
代码主要实现的是在通过一个桥梁对象,来实现信号的传递,从而实现了对象间的通信。
其中 connect(SigTranSport::Instance(),SIGNAL(DsSigDo()),&ds,SIGNAL(SigDo())); 这个函数是来实现信号的传递。
代码下载地址:
点击打开链接