Qt学习及使用_第3部分_Qt框架功能概述---信号与槽

前言
        

        学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面.

        参考书:<Qt 6 C++开发指南>(以下称"本书"),继承关系沿用本书说法:父类/子类,而非传统C++使用基类/派生类

        标识说明:概念用粗体+倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字),

                        本书原话内容用深蓝色标识,比较重要的内容用加粗倾斜下划线深蓝色标识

引入

        Qt框架功能是本书的核心内容,本贴展开对信号与槽的理解

简介

        本书P28第3段:信号与槽是Qt编程的基础,也是Qt的一大创新.有了信号与槽的编程机制,在Qt中处理界面上各个组件的交互操作就变得比较直观和简单.

        ---解读:信号与槽的设计思想是让界面上各个组件的交互操作直观和简单.

        举个简单的例子:有个对话框,有"确定"和"取消"两个按钮,点击"确定"后执行某个操作(假设打开另一个对话框)并关闭对话框,点击"取消"按钮后不执行其它操作,关闭对话框(图略)

        这2个操作由2个信号-槽来完成.其中点击"确定"按钮是一个信号,槽函数是与之对应的确定效果.同理点击"取消"按钮也是一个信号,槽函数是与之对应的取消效果.

信号与槽发生了什么

        信号和槽都是函数,发生了数据变化.他们的逻辑是"当信号函数被调用,槽函数被执行".

        本书P28第6段:信号与槽关联是用函数QObject::connect()实现的,使用函数connect()的基本格式如下:

QObject::connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));

        这是QObject类的静态函数,可以直接调用(非对象调用),而QObject是大部分Qt类的基类,所以可以直接写成

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

        sender是发射信号的对象的名称;signal是信号,信号可以看作特殊的函数,需要带有括号,有参数时还需要指明各参数类型;receiver是接收信号的对象的名称;slot是槽函数,需要带有括号,有参数时还需要指明各参数类型.SIGNAL和SLOT是Qt的宏,分别用于指明信号和槽函数.

信号与槽的使用规则

        1.一个信号可以连接多个槽函数

                ---表示:一个因多个果

        2.多个信号可以连接同一个槽函数

                ---表示多个因指向一个果

        3.一个信号可以连接另一个信号

                ---表示一个因指向另一个因

        4.严格情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数.如果参数不匹配,会出现编译错误或运行错误.        

                ---笔者不理解划线部分,信号参数个数和槽参数个数有关系?

        5.在使用信号与槽的类中,必须在类的定义中插入宏Q_OBJECT

        6.当一个信号被发射时,与其关联的槽函数通常被立即运行,就像正常调用函数一样.只有当信号关联的所有槽函数运行完毕后,才运行发射信号处后面的代码.

其他

        信号与槽的操作是比较简单的,但是本书示例的代码P29~P31,以及P53~P57部分不是太好读,要和后面的具体类相结合,同时信号与槽在后面应用十分广泛,所以这部分内容在后面的章节用到时再做理解.

信号与槽的底层机制分析

        有了前面对元数据和元对象的理解,尝试理解信号与槽的实现.

=============================内容分割线↓===================================

以下内容属于作者发散思考,不保证对错.

方案一

        信号与槽的逻辑联系:当信号对象的方法被调用,随即调用槽对象的函数.假设有一个类专门处理信号与槽

/*伪代码*/
struct Signal_Slot{
        QObject     sender;
        QMetaMethod sd_qm;
        QObject     receiver;
        QMetaMethod rv_qm; 
}

        程序中可以定义多个connect函数,每定义一个connect函数,生成一个Signal_Slot对象,并把信号对象和槽对象的元数据---对象类型,方法名称,参数等信息传入.建立一个信号与槽的集合

vector<Signal_Slot> vss;

        1>程序运行时,有一个函数进行状态采集---程序反复运行,一直扫描和采集.扫描内容是输入焦点对象,输入一般是鼠标和键盘,例如鼠标左键点击/右键点击,键盘按下了某个键;焦点对象是笔者自己给的定义,例如鼠标正移动到某个对象上,或者键盘用tab键指向的对象;比如"点击OK键",需要同时满足"鼠标移动到了OK键上"和"鼠标左键点击"的判定.输入和焦点对象被记录下来进入2>.焦点对象的采集,需要比对鼠标位置(位置)和对象所在位置(坐标).

        2>根据扫描的状态---实际上是查找信号函数(可能有可能没有),遍历vss,如果遍历到有数据存在---说明信号函数和槽函数都有定义,则执行槽函数.

        这种思路需要元数据的支持,可能还需要对编译器做修改.

方案二

        直接connect函数的定义表达,这需要满足几个条件:

                有一个类型能代表所有类型对象,

                有一个函数指针能指向所有类型函数;

                类型和函数指针合在一起能表示对象方法.

        前面的状态采集和查找仍需要

=============================内容分割线↑===================================

小结

        信号与槽函数的简单理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重庆彭枫

你的鼓励是我创作的动力,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值