Qt -信号槽实现原理

一 简介

QT信号槽的实现实质是什么?
“回调函数”

简要说一下信号与槽的底层原理。
信号与槽的实现是借助了Qt 的元对象系统,元对象系统有一个元对象编译器,程序编译之前会有一个预处理过程,预处理将一个类/对象中的信号,槽的字符串值分别保存在一个容器中,可能是字符串或者其他的有序容器。

二 例子

简单实现

#include <map>
# define slot
# define siginal protected
# define emit

class Object;

struct MetaObject//元对象 每个Object有一个,保存自己拥有的信号和槽函数
{
	const char* sig_names;
	const char* slts_names;
	static void active(Object* sender, int idx);
};

struct Connection//保存接收方及其序号
{
	Object* receiver;
	int method;
};

typedef std::multimap<int, Connection> ConnectionMap;
//<信号,接收方>每个Object有一个,保存自己的信号发出时需要通知的接收方。每个信号的接收方可能不止一个,用multimap
typedef std::multimap<int, Connection>::iterator ConnectionMapIt;

static int find_string(const char* str, const char* substr)
{
	if (strlen(str) < strlen(substr))
		return -1;
	int idx = 0;
	int len = strlen(substr);
	bool start = true;
	const char* pos = str;
	while (*pos) 
	{
		if (start && !strncmp(pos, substr, len) && pos[len] == '\n')
			return idx;
		start = false;
		if (*pos == '\n') 
		{
			idx++;
			start = true;
		}
		pos++;
	}
	return -1;
}

class Object
{
	friend class MetaObject;
public:
	Object() {};
	virtual ~Object() {};
	static void connect(Object*sender, const char*sig, Object*receiver, const char*slt);
	void testSignal() { emit sig1(); }//测试函数

siginal:
	void sig1() //信号
	{ 
		cout << "信号发出" << endl;
		MetaObject::active(this, 0);
	}

public slot:
	void slot1() { cout << "槽函数执行" << endl; }//槽函数

private:
	static MetaObject meta;//保存自己拥有的信号和槽函数
	ConnectionMap connections;//multimap<int, Connection>,
	void metacall(int idx);//根据key去查询对应的槽函数
};

static const char sig_names[] = "sig1\n";//保存对象中所有信号的字符串的容器
static const char slts_names[] = "slot1\n";//保存对象中所有槽函数字符串的容器
MetaObject Object::meta = { sig_names, slts_names };//初始化元对象

void Object::metacall(int idx)//根据key去查询对应的槽函数
{
	switch (idx) 
	{
	case 0:
		slot1();
		break;
	default:
		break;
	};
}

void Object::connect(Object*sender, const char*sig, Object*receiver, const char*slt)//静态成员函数  connect建立信号与槽的连接
{
	int sig_idx = find_string(sender->meta.sig_names, sig);//查询有没有这个信号和槽函数
	int slt_idx = find_string(receiver->meta.slts_names, slt);
	if (sig_idx == -1 || slt_idx == -1) 
	{
		perror("signal or slot not found!");
	}
	else //添加
	{
		Connection c = { receiver, slt_idx };//保存接收方及其槽函数id
		sender->connections.insert(std::pair<int, Connection>(sig_idx, c));//发送方保存接收方信息
	}
}

void MetaObject::active(Object* sender, int idx)//信号发出,根据发出者找出它的接收方
{
	ConnectionMapIt it;
	std::pair<ConnectionMapIt, ConnectionMapIt> ret;
	ret = sender->connections.equal_range(idx);//equal_range主要是找在multimap中的key相等的value,也是一个迭代器
	for (it = ret.first; it != ret.second; ++it) 
	{
		Connection c = (*it).second;//获取之前保存的接受方消息
		c.receiver->metacall(c.method);//接收方执行之前绑定的槽函数
	}
}

int main()
{
	Object obj1, obj2;
	Object::connect(&obj1, "sig1", &obj2, "slot1");//连接信号
	obj1.testSignal();

	system("pause");
	return 0;
}

结果
在这里插入图片描述

参考文章

QT信号槽

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Qt是一款流行的跨平台C++框架,有着强大的功能和丰富的类库。Qt的核心机制包括Qt的元对象系统和信号机制。 Qt的元对象系统是Qt的一个重要特性,它是Qt实现反射的基础。在C++中,反射能够在运行时获取类的信息,如类名、属性、方法等,并在运行时动态地创建、调用对象。Qt的元对象系统通过为每个QObject派生的子类生成一个元对象,实现了C++的反射机制。元对象系统使得Qt能够在运行时获取QObject派生类的信息,并提供了一系列函数来操作这些对象。 Qt信号机制是Qt的核心机制之一,它用于实现对象之间的通信。信号机制基于发布-订阅模式,其中一个对象发送信号,而另一个对象通过连接到这个信号函数来接收信号并进行相应的处理。信号机制具有松耦合的特性,可以实现对象之间的解耦。 在信号机制中,信号是由QObject派生类定义的特殊函数,用于声明某个特定事件发生时要发送的信号函数是QObject派生类中的普通函数,用于接收这个信号,并且执行相应的处理逻辑。信号通过信号连接函数进行连接,这样当信号触发时,与之连接的函数就会被自动调用。 Qt的元对象系统和信号机制是Qt强大功能的基石。元对象系统实现了C++的反射机制,允许在运行时获取和操作对象的信息。信号机制使对象之间的通信变得简单和易用,提供了一种灵活而高效的方式来实现对象间的解耦。通过这些核心机制,Qt能够帮助开发人员更快速、更简便地开发高质量的跨平台应用程序。 ### 回答2: qt核心机制是指Qt框架的底层机制,主要包括Qt元对象系统和Qt信号原理。 Qt元对象系统是Qt框架中的一个重要概念,它在C++语言的基础上添加了一套元对象(Meta Object)系统。元对象系统在编译过程中生成了额外的代码,使得我们可以在运行时获得更多的对象信息。通过元对象系统,Qt实现了信号机制、宏(MOC)编译和反射等功能。元对象系统实际上是一种面向对象的编程方式,通过它可以实现Qt特有的功能,如动态属性、动态信号等。 Qt信号原理是Qt框架中的一个重要特性,用于对象间的通信。信号是一种异步通信方式,通过信号发送者(Sender)发送信号,接收者(Receiver)通过函数(Slot)响应信号信号是通过元对象系统实现的,编译器会在MOC编译阶段解析信号的声明,并在运行时建立连接关系。这种机制使得Qt程序的耦合性更低,灵活性更高,同时也为多线程编程提供了一种方便的方式。 总的来说,Qt核心机制包括了Qt的元对象系统和信号原理。元对象系统为Qt框架提供了反射、动态属性和动态信号等功能,信号机制实现了对象间的异步通信。这些机制使得Qt框架具有高度的可扩展性、灵活性和跨平台性,为开发者提供了一种便捷、高效的方式来构建应用程序。 ### 回答3: Qt是一种跨平台的应用程序框架,具有丰富的功能和强大的性能。Qt核心机制是指Qt框架的基础机制,包括Qt元对象系统和Qt信号原理。 Qt元对象系统是Qt框架的核心组成之一,用于实现Qt的一些特殊功能,如信号机制和动态属性。Qt元对象系统通过将所有的类对象都派生自QObject基类,实现了一种反射机制,使得对象之间可以动态地连接和交互。通过使用元对象系统,Qt可以实现面向对象编程的高级特性,如对象间的信号的连接,对象的属性系统以及对象的内省(即动态获取对象的属性和方法信息)等。 Qt信号原理是Qt框架实现事件驱动的关键机制。信号机制允许不同对象之间进行松散的耦合,通过信号的方式进行通信。信号是一种特殊的成员函数,用于表示某个事件的发生,是一种普通的成员函数,用于响应信号的发出。当一个信号被发出时,Qt框架会自动将信号进行匹配,并调用对应的函数。这种机制使得对象之间的通信更加灵活和高效,可以实现事件的传递和处理,避免了显式的函数调用和回调函数的使用。 综上所述,Qt的核心机制包括Qt元对象系统和Qt信号原理。通过元对象系统,Qt实现了一种反射机制,使得对象之间可以动态地连接和交互;通过信号机制,Qt实现了一种松散耦合的事件处理方式,提高了对象之间的通信效率和灵活性。这些机制是Qt框架的重要组成部分,为开发者提供了更加强大和易用的工具和功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值