Qt里的信号与槽原理

一、什么是信号与槽机制?

  ​ 信号和槽(Signal & Slot)用于两个对象(object)进行交流,通俗地来说,就是一个对象发出什么信号,另一个对象执行相应的动作(比如跑步比赛中,裁判员发出枪响信号,运动员开始起跑)。

  信号(Signal):相当于发出一个事件通知。

  槽(Slot):槽其实是一个函数,为了响应信号而执行的一系列的指令。

  连接(connect):这个连接的过程,就是,我们指定什么样的信号执行什么样的槽函数。

  Qt里只有从QOBject派生来的类,才支持信号与槽。主要分为两类:1、Qt类自带的;2、用户自定义的。

二、信号

  对于Qt中自带的信号而言,一般只需要知道有哪些信号,直接去使用即可,Qt中常见的几个信号如下:

void clicked(bool checked = false)

void pressed()

void released()

void toggled(bool check)

  如果想要使用自定义的信号, 首先要编写新的类并且让其继承Qt的某些标准类,我们自己编写的类想要在Qt中使用使用信号槽机制, 那么必须要满足的如下条件:
     1. 这个类必须从QObject类或者是其子类进行派生
     2. 在定义类的头文件中加入 Q_OBJECT 宏
  要求:
     1. 信号是类的成员函数
     2. 返回值是 void 类型
     3. 信号的名字可以根据实际情况进行指定
     4. 参数可以随意指定, 信号也支持重载 void signal_test(int, int, char);
     5. 信号需要使用 signals 关键字进行声明, 使用方法类似于public等关键字
     6. 信号函数只需要声明
     7. 在程序中发送自定义信号: 发送信号的本质就是调用信号函数

  当我们写下一下emit signal代码的时候,与这个signal相连接的slot就会被调用,那么这个调用是如何发生的呢?让我们来逐一解开其中的谜团。

  来看一段例子代码:

class ZMytestObj : public QObject
{
Q_OBJECT
signals:
void sigMenuClicked();
void sigBtnClicked();
};

  编译器在做完预处理之后的代码如下:


// SIGNAL 0
void ZMytestObj::sigMenuClicked()
{
QMetaObject::activate(this, &staticMetaObject, 0, 0);
}
 
// SIGNAL 1
void ZMytestObj::sigBtnClicked()
{
QMetaObject::activate(this, &staticMetaObject, 1, 0);

所以信号函数也可以自己写成这样的方式去定义。

三、槽函数

  特点为:
      1.返回值void
      2.参数可以有,参数的类型和个数需要和对应的信号对应起来,参数个数可以比信号少,但不能多void slot_test(int);与前面的void signal_test(int, int, char)对应

四、连接信号槽

  connect函数

 //QT4
 connect(m_pPushBtn, SIGNAL(clicked(bool)), &signalTest, SLOT(slots_TestSlot1()));

 //QT5
 connect(m_pPushBtn, &QPushButton::clicked, &signalTest, &CSignalTest::slots_TestSlot1);

   注意:
      1.一个信号可以连接到多个槽函数
         信号触发之后,所有槽函数都被调用,调用顺序不确定

      2.一个槽函数,可以被多个信号连接
         其中某一个信号触发时,槽函数都将被调用

      3.connect可以连接信号与信号
         connect(m_pPushBtn, SIGNAL(clicked(bool)), &signalTest, SIGNAL(signals_TestSignls()));

你可能感兴趣的:(#,qt,qt,开发语言,c++)