Qt信号与槽机制(signal & slot)

1、简介

信号槽机制与Windows下消息机制类似,消息机制是基于回调函数,Qt中用信号与槽来代替函数指针,使程序更安全简洁。

信号和槽机制是 Qt 的核心机制,可以让编程人员将互不相关的对象绑定在一起,实现对象之间的通信。

信号

当对象改变其状态时,信号就由该对象发射 (emit) 出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号。这样就做到了真正的信息封装,能确保对象被当作一个真正的软件组件来使用。

用于接收信号,而且槽只是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。而且对象并不了解具体的通信机制。

信号与槽的连接

所有从 QObject 或其子类 ( 例如 Qwidget ) 派生的类都能够包含信号和槽。因为信号与槽的连接是通过 QObject 的 connect() 成员函数来实现的。

connect(sender, SIGNAL(signal), receiver, SLOT(slot));
其中 sender 与 receiver 是指向对象的指针,SIGNAL() 与 SLOT() 是转换信号与槽的宏。

2、特点

一个信号可以连接多个槽

当信号发射时,会以不确定的顺序一个接一个的调用各个槽。

多个信号可以连接同一个槽

即无论是哪一个信号被发射,都会调用这个槽。

信号直接可以相互连接

发射第一个信号时,也会发射第二个信号。

连接可以被移除

这种情况用得比较少,因为在对象被删除时,Qt会自动移除与这个对象相关的所有连接。语法如下:

disconnect(sender, SIGNAL(signal), receiver, SLOT(slot));

3、注意事项

信号与槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时也有可能产生死循环。

因此,在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样信号。例如 , 在前面给出的例子中如果在 mySlot() 槽函数中加上语句 emit mySignal() 即可形成死循环。

Qt4.6以后连接到同一个信号的多个槽的执行顺序是确定的,按connect的先后顺序。

宏定义不能用在 signal 和 slot 的参数中。

信号和槽的参数个数与类型必须一致。

4、程序举例

这个demo程序由一个Label和PushButton组成,点击按钮,在label上获取当前系统时间,这个涉及到的知识点有:信号与槽的参数类型不同时如何连接、自定义槽函数、自定义信号。

4.1 新建一个Qt Application,Base Class选择QDialog,类名为getTime

4.2 getTime.h内容

#ifndef GETTIME_H
#define GETTIME_H

#include <QtWidgets/QDialog>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QTime>
#include "ui_gettime.h"

class getTime : public QDialog
{
	Q_OBJECT

public:
	getTime(QWidget *parent = 0);
	~getTime();

private:
	Ui::getTimeClass ui;
	QLabel *label;
	QPushButton *btn;

	public slots:
		void currentTime();

signals:
		void getData(QString);	
};


#endif // GETTIME_H

4.3 getTime.cpp内容

#include "gettime.h"

getTime::getTime(QWidget *parent)
	: QDialog(parent)
{
	this->resize(300,400);
	label = new QLabel("label",this);
	btn = new QPushButton("getTime",this);
	label->move(150,200);
	btn->move(125,300);

	connect(btn,SIGNAL(clicked()),this,SLOT(currentTime()));

	connect(this,SIGNAL(getData(QString)),label,SLOT(setText(QString)));

	ui.setupUi(this);
}

getTime::~getTime()
{
	delete label;
	delete btn;
}

void getTime::currentTime()
{
	emit getData(QTime::currentTime().toString("hh:mm"));
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值