自学内容网 自学内容网

【Qt】信号和槽——信号和槽的概念、信号和槽的使用、信号和槽的优缺点、自定义信号和槽、信号和槽的断开

Qt

在这里插入图片描述
  

1. 信号和槽的概念

  信号是什么:

  在Linux中,我们知道信号是一种异步的事件通知机制,用于通知进程某个事件已经发生。它是进程间通信的一种方式。

  回顾之前的信号的三个特点,信号由谁产生,信号的类型,信号所对应的触发事件。我们可以简单的理解:Qt中的信号其实和linux的类似,本质就是让用户进行交互,触发对应的交互事件。

  所以在Qt中,信号的详细解释:就是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时 Qt 对应的窗口类会发出某个信号,以此对用户的操作做出反应。因此,信号的本质就是事件

  
  ‘’ 点击按钮、鼠标移动、鼠标按下、鼠标释放以及键盘输入… ‘’ 这些都是事件,Qt怎么样将这些信号事件通过不同的形式传递给使用者?通过函数来表示信号。

  

  槽是什么:

  槽(Slot)就是对信号响应的函数。 槽就是一个函数,与一般的 C++ 函数是一样的,可以定义在类的任何位置(public、protected 或 private),可以具有任何参数,可以被重载,也可以被直接调用(但是不能有默认参数)。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

  
  所以,在 Qt 中,用户和控件的每次交互过程称为一个事件,每个事件都会发出一个信号。Qt 中的所有控件都具有接收信号的能力,且一个控件可接收多个不同信号。对于接收到的每个信号,控件会做出相应响应动作。在 Qt 中,对信号做出的响应动作称之为槽。信号和槽是 Qt 特有的消息传输机制,能将相互独立的控件关联起来,通过信号和槽机制可关联起来,实现不同的效果。

  
  信号和槽的联系和区别:

  (1)信号和槽机制底层是通过函数间的相互调用实现的。每个信号都可以用函数来表示,称为信号函数;每个槽也可以用函数表示,称为槽函数。

  (2)信号函数和槽函数通常位于某个类中,和普通的成员函数相比,它们的特别之处在于:

  1. 信号函数用 signals 关键字修饰,槽函数用 public slots、protected slots 或者 private slots 修饰。signals 和 slots 是 Qt 在 C++ 的基础上扩展的关键字,专门用来指明信号函数和槽函数;

  2. 信号函数只需要声明,不需要定义(实现),而槽函数需要定义(实现)

  信号函数的定义是 Qt 自动在编译程序之前生成的。编写 Qt应用程序的程序员无需关注。这种自动生成代码的机制称为元编程(Meta Programming)。这种操作在很多场景中都能见到。

  

2. 信号和槽的使用

  在 Qt 中,QObject 类提供了一个静态成员函数 connect (),该函数专门用来关联指定的信号函数和槽函数

  关于 QObject,QObject 是 Qt 内置的父类。Qt 中提供的很多类都是直接或者间接继承自 QObject。

  
connect() 函数原型:

connect(const QObject *sender, 
const char * signal ,
const QObject * receiver , 
const char * method , 
Qt::ConnectionType type = Qt::AutoConnection )

  
参数说明如下:

  sender:信号的发送者。

  signal:发送的信号(信号函数)。

  receiver:信号的接收者。

  method:接收信号的槽函数。

  type:用于指定关联方式,默认的关联方式为 Qt::AutoConnection,通常不需要手动设定。

  

  接下来我们使用Qt内置提供的信号和槽,来实现信号和槽的连接。

  代码示例:创建一个关闭按钮,点击该按钮,窗口关闭。

  

  1. 我们创建QPushButton对象,并且调整该按钮的位置、字体大小,连接信号和槽,这里的信号是QPushButton::clicked,是Qt的内置信号,表示按下按钮后的事件,槽函数是内置的Widget::close,表示关闭这个窗口。

    connect(btn,&QPushButton::clicked,this,&Widget::close);可以理解为:如果我们按下btn按钮时,按钮向自己的父类Widget界面发送了一个信号,信号告知Widget应该执行close这个函数。

在这里插入图片描述

  

  1. 运行Qt程序,我们点击图中的关闭窗口按钮。

在这里插入图片描述

  

  1. 可以看到窗口被关闭了。

在这里插入图片描述

  

3. 信号和槽的优缺点

  优点:松散耦合。 信号发送者不需要知道发出的信号被哪个对象的槽函数接收,槽函数也不需要知道哪些信号关联了自己,Qt 的信号槽机制保证了信号与槽函数的调用。支持信号槽机制的类或者父类必须继承于 QObject 类。

  缺点:效率较低。 与回调函数相比,信号和槽稍微慢一些,因为它们提供了更高的灵活性,尽管在实际应用程序中差别不大。通过信号调用的槽函数比直接调用的速度慢约 10 倍(这是定位信号的接收对象所需的开销;遍历所有关联;编组 / 解组传递的参数;多线程时,信号可能需要排队),这种调用速度对性能要求不是非常高的场景是可以忽略的,是可以满足绝大部分场景。

  

4. 自定义信号和槽

  上面的信号的槽都是使用了内置的类型,当然我们也可以自定义我们的信号和槽函数:

  代码示例(自定义槽函数):我们使用我们自己定义的closeWidget函数代替内置的Widget::close函数。

  
  自定义信号函数书注意自定义信号函数必须写到 “signals” 下;返回值为 void,只需要声明,不需要实现;可以有参数,也可以发生重载。

  自定义槽函数注意:可以写在 “public slots”下或 “public”下;返回值为 void,需要声明,也需要实现;可以有参数,可以发生重载。
  

  1. 按钮的按下事件和我们自定义的槽函数closeWidget连接,实现了关闭窗口的同时还可以在Qt的编译界面输出 " 窗口关闭 " 。

在这里插入图片描述

  

  1. 运行Qt程序,并且点击关闭窗口。
    在这里插入图片描述
      

  2. 窗口成功关闭并且输出了语句。
    在这里插入图片描述

  

  代码示例(自定义信号):我们使用自己创建的信号和内置的close函数连接,发送信号的过程使用我们自己定义的槽函数。

  1. 我们自定义了信号mySignal和槽函数closeWidget。

在这里插入图片描述
  

  1. 将自定义槽函数closeWidget和按钮按下事件连接,槽函数触发事件为发送一个自定义信号mySignal;将自定义信号mySignal和内置函数Widget::close连接,this接收到了信号就关闭窗口。

在这里插入图片描述

  

  1. 运行Qt程序,点击 “ 发送关闭窗口信号 ” 。

在这里插入图片描述
  

  1. 槽函数成功发送信号,信号成功触发close内置槽函数,窗口关闭。

在这里插入图片描述

  

5. 信号和槽的断开

  信号与槽的断开使用 disconnect 即可完成。disconnect 的用法和 connect 基本一致。

  断开了信号和槽的连接,无法关闭窗口了。

在这里插入图片描述

            


原文地址:https://blog.csdn.net/Crocodile1006/article/details/143019961

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!