目录
- 0.Q_OBJECT宏
- 1.信号和槽概述
- 1.信号
- 2.槽
- 3.说明
- 2.信号和槽的使用
- 1.连接信号和槽
- 2.查看内置信号和槽
0.Q_OBJECT宏
- Qt如果要让某个类能够使用信号槽,则必须要在类最开始的地方,写下
Q_OBJECT
宏
1.信号和槽概述
1.信号
- 在Qt中,⽤⼾和控件的每次交互过程称为⼀个事件
- 例如:"⽤⼾点击按钮"是⼀个事件,"⽤⼾关闭窗⼝"也是⼀个事件
- 每个事件都会发出⼀个信号
- 例如:⽤⼾点击按钮会发出"按钮被点击"的信号,⽤⼾关闭窗⼝会发出"窗⼝被关闭"的信号
- 信号的本质:
- 信号是由于⽤⼾对窗⼝或控件进⾏了某些操作,导致窗⼝或控件产⽣了某个特定事件,这时Qt对应的窗⼝类会发出某个信号,以此对⽤⼾的操作做出反应
- 因此,信号的本质就是事件
- Qt中信号是通过什么形式呈现给使⽤者的呢?
- 对哪个窗⼝进⾏操作,哪个窗⼝就可以捕捉到这些被触发的事件
- 对于使⽤者来说,触发了⼀个事件就可以得到Qt框架发出的某个特定信号
- 信号的呈现形式就是函数
- 也就是说某个事件产⽣了,Qt框架就会调⽤某个对应的信号函数,通知使⽤者
- 在Qt中信号的发出者是某个实例化的类对象
2.槽
-
Qt中的**所有控件都具有接收信号的能⼒,⼀个控件还可以接收多个不同的信号**
-
对于接收到的每个信号,控件都会做出相应的响应动作
- 按钮所在的窗⼝接收到"按钮被点击"的信号后,会做出"关闭⾃⼰"的响应动作
- 输⼊框⾃⼰接收到"输⼊框被点击"的信号后,会做出"显⽰闪烁的光标,等待⽤⼾输⼊数据"的响应动作
-
在Qt中,对信号做出的响应动作就称之为槽
-
信号和槽是Qt特有的消息传输机制,它能将相互独⽴的控件关联起来。
- 例如:“按钮"和"窗⼝” 本⾝是两个独⽴的控件,点击"按钮"并不会对"窗⼝"造成任何影响。通过信号和槽机制,可以将"按钮"和"窗⼝"关联起来,实现"点击按钮会使窗⼝关闭"的效果
- 例如:“按钮"和"窗⼝” 本⾝是两个独⽴的控件,点击"按钮"并不会对"窗⼝"造成任何影响。通过信号和槽机制,可以将"按钮"和"窗⼝"关联起来,实现"点击按钮会使窗⼝关闭"的效果
-
槽的本质:
- 槽(Slot)就是对信号响应的函数
- 槽就是⼀个函数,与⼀般的C++成员函数是⼀样的
- 可以定义在类的任何位置(
public, protected, private
) - 可以具有任何参数
- 可以被重载
- 也可以被直接调⽤(但是不能有默认参数)
- 可以定义在类的任何位置(
- 槽函数与⼀般的函数不同的是:槽函数可以与⼀个信号关联,当信号被发射时,关联的槽函数被⾃动执⾏
3.说明
- 信号和槽机制底层是通过函数间的相互调⽤实现的
- 每个信号都可以⽤函数来表⽰,称为信号函数
- 每个槽也可以⽤函数表⽰,称为槽函数
- 例如:
- "按钮被按下"这个信号可以⽤
clicked()
表⽰,"窗⼝关闭"这个槽可以⽤close()
表⽰, - 假如使⽤信号和槽机制实现:"点击按钮会关闭窗⼝"的功能,其实就是
clicked()
调⽤close()
的效果
- "按钮被按下"这个信号可以⽤
- 信号函数和槽函数通常位于某个类中,和普通的成员函数相⽐,它们的特别之处在于
- 信号函数⽤
signals
关键字修饰 - 槽函数⽤
public slots, protected slots, private slots
修饰 signals
和slots
是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
必须是匹配的 - 即:如果
sender
是QPushButton*
,那么signal
必须是QPushButton
内置的信号(父类的信号),不能是其他类的信号
- 要求和
receiver
:信号的接收者 --> 哪个对象负责处理method
:接收信号的槽函数 --> 这个对象该怎么处理type
:⽤于指定关联⽅式,默认的关联⽅式为Qt::AutoConnection
,通常不需要⼿动设定
- 疑问:为什么
signal
和method
类型是char*
?- 这个函数声明,是旧版本的Qt的
connect
的函数声明- 此时使用要搭配
SIGNAL
和SLOT
宏使用 - 例如:
connect(button, SIGNAL(&QPushButton::clicked), this, SLOT(&Widget::close));
- 此时使用要搭配
- Qt5开始,对上述写法做出了简化,不再需要
SIGNAL
和SLOT
宏了,提供了connect
的重载版本,该版本中,signal
和method
成了泛型参数,允许传入任意类型的指针了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)
- 这个函数声明,是旧版本的Qt的
2.查看内置信号和槽
- 系统⾃带的信号和槽通常是通过"Qt帮助⽂档"来查询
- 如果没有找到,可以继续去⽗类中查找