[Qt][信号与槽][上]详细讲解

DieSnowK 2024-08-12 10:05:03 阅读 85

目录

0.Q_OBJECT宏1.信号和槽概述1.信号2.槽3.说明

2.信号和槽的使用1.连接信号和槽2.查看内置信号和槽

0.Q_OBJECT宏

Qt如果要让某个类能够使用信号槽,则必须要在类最开始的地方,写下<code>Q_OBJECT宏

1.信号和槽概述

1.信号

在Qt中,⽤⼾和控件的每次交互过程称为⼀个事件

例如:"⽤⼾点击按钮"是⼀个事件,"⽤⼾关闭窗⼝"也是⼀个事件 每个事件都会发出⼀个信号

例如:⽤⼾点击按钮会发出"按钮被点击"的信号,⽤⼾关闭窗⼝会发出"窗⼝被关闭"的信号 信号的本质

信号是由于⽤⼾对窗⼝或控件进⾏了某些操作,导致窗⼝或控件产⽣了某个特定事件,这时Qt对应的窗⼝类会发出某个信号,以此对⽤⼾的操作做出反应因此,信号的本质就是事件 Qt中信号是通过什么形式呈现给使⽤者的呢?

对哪个窗⼝进⾏操作,哪个窗⼝就可以捕捉到这些被触发的事件对于使⽤者来说,触发了⼀个事件就可以得到Qt框架发出的某个特定信号信号的呈现形式就是函数

也就是说某个事件产⽣了,Qt框架就会调⽤某个对应的信号函数,通知使⽤者 在Qt中信号的发出者是某个实例化的类对象

2.槽

Qt中的**所有控件都具有接收信号的能⼒,⼀个控件还可以接收多个不同的信号**

对于接收到的每个信号,控件都会做出相应的响应动作

按钮所在的窗⼝接收到"按钮被点击"的信号后,会做出"关闭⾃⼰"的响应动作输⼊框⾃⼰接收到"输⼊框被点击"的信号后,会做出"显⽰闪烁的光标,等待⽤⼾输⼊数据"的响应动作

在Qt中,对信号做出的响应动作就称之为槽

信号和槽是Qt特有的消息传输机制,它能将相互独⽴的控件关联起来

例如:“按钮"和"窗⼝” 本⾝是两个独⽴的控件,点击"按钮"并不会对"窗⼝"造成任何影响。通过信号和槽机制,可以将"按钮"和"窗⼝"关联起来,实现"点击按钮会使窗⼝关闭"的效果

请添加图片描述

槽的本质

槽(Slot)就是对信号响应的函数槽就是⼀个函数,与⼀般的C++成员函数是⼀样的

可以定义在类的任何位置(<code>public, protected, private)可以具有任何参数可以被重载也可以被直接调⽤(但是不能有默认参数) 函数与⼀般的函数不同的是槽函数可以与⼀个信号关联,当信号被发射时,关联的槽函数被⾃动执⾏

3.说明

信号和槽机制底层是通过函数间的相互调⽤实现的

每个信号都可以⽤函数来表⽰,称为信号函数每个槽也可以⽤函数表⽰,称为槽函数例如

"按钮被按下"这个信号可以⽤clicked()表⽰,"窗⼝关闭"这个槽可以⽤close()表⽰,假如使⽤信号和槽机制实现:"点击按钮会关闭窗⼝"的功能,其实就是clicked()调⽤close()的效果 信号函数和槽函数通常位于某个类中,和普通的成员函数相⽐,它们的特别之处在于

信号函数⽤signals关键字修饰槽函数⽤public slots, protected slots, private slots修饰signalsslots是Qt在C++的基础上扩展的关键字,专⻔⽤来指明信号函数和槽函数 信号函数只需要声明,不需要定义(实现),⽽槽函数需要定义(实现)

信号函数的定义是Qt⾃动在编译程序之前⽣成的,编写Qt应⽤程序的程序员⽆需关注这种⾃动⽣成代码的机制称为元编程(MetaProgramming)


2.信号和槽的使用

1.连接信号和槽

QObject类提供了⼀个静态成员函数connect(),专⻔⽤来关联指定的信号函数和槽函数函数原型

connect(const QObject* sender,

const char* signal,

const QObject* receiver,

const char* method,

Qt::ConnectionType type = Qt::AutoConnection)

参数

sender:信号的发送者 -> 当前信号由哪个空间发出signal:发送的信号(信号函数)

要求和sender必须是匹配的:如果senderQPushButton*,那么signal必须是QPushButton内置的信号(父类的信号),不能是其他类的信号 receiver:信号的接收者 --> 哪个对象负责处理method:接收信号的槽函数 --> 这个对象该怎么处理type:⽤于指定关联⽅式,默认的关联⽅式为Qt::AutoConnection通常不需要⼿动设定 疑问:为什么signalmethod类型是char*

这个函数声明,是旧版本的Qt的connect的函数声明

此时使用要搭配SIGNALSLOT使用例如connect(button, SIGNAL(&QPushButton::clicked), this, SLOT(&Widget::close)); Qt5开始,对上述写法做出了简化,不再需要SIGNALSLOT了,提供了connect的重载版本,该版本中,signalmethod成了泛型参数,允许传入任意类型的指针了

template <typename Func1, typename Func2>

static inline QMetaObject::Connection

connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender,

Func1 signal,

const typename QtPrivate::ContextTypeForFunctor<Func2>::ContextType *context,

Func2 &&slot,

Qt::ConnectionType type = Qt::AutoConnection)

2.查看内置信号和槽

系统⾃带的信号和槽通常是通过"Qt帮助⽂档"来查询如果没有找到,可以继续去⽗类中查找



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。