【Qt】自定义信号和槽函数

06-01 1349阅读

🏠个人主页:Yui_

🍑操作环境:Qt Creator

🚀所属专栏:Qt

【Qt】自定义信号和槽函数

文章目录

  • 1. 自定义槽函数
    • 1.1 基础语法
    • 1.2 使用`connect`连接信号
    • 1.3 使用函数名字的方式来自动连接
    • 2.自定义信号函数
    • 3.知识补充
      • 3.1 signals和slots
      • 3.2 emit
      • 4. 总结

        在Qt中,允许自定义信号和槽函数。

        其中自定义槽函数是非常频繁的,但是自定义信号函数频率较低,这是由于Qt中内置的信号几乎可以覆盖到用户的操作,简单来说就是用户的操作是可以穷举的。尽管如此,学习自定义的信号函数也是有必要的。

        在下面的文章,我们会先讲解更重要的自定义槽函数再去讲解自定义信号。

        1. 自定义槽函数

        1.1 基础语法

        • 在早期的Qt版本要求槽函数必须写到public solts下,但是在现在的高版本的Qt(Qt5及以上)允许写到类public作用域或者全局下。
        • 返回值为void,需要声明,也需要实现。
        • 可以到参数,可以重载。

          绑定自定义的槽函数有两种方法:

          1. 通过connect函数连接信号。
          2. 通过函数名字的方式来自动连接。

            下面会详细的演示这两种方法。

          1.2 使用connect连接信号

          这种方式在之前的文章就已经有所涉及了。

          关于connect函数的介绍可以看这篇文章【Qt-信号与槽】connect函数的用法-CSDN博客

          #include "widget.h"
          #include "ui_widget.h"
          Widget::Widget(QWidget *parent)
              : QWidget(parent)
              , ui(new Ui::Widget)
          {
              ui->setupUi(this);
              button = new QPushButton(this);
              button->setText("我是一个按钮~");
              button->move(100,100); // 移动位置到(100,100)像素
              connect(button,&QPushButton::clicked,this,&Widget::handle);
          }
          Widget::~Widget()
          {
              delete ui;
          }
          void Widget::handle()
          {
              button->setText("被点击了~");
          }
          

          头文件:

          #ifndef WIDGET_H
          #define WIDGET_H
          #include 
          #include 
          QT_BEGIN_NAMESPACE
          namespace Ui { class Widget; }
          QT_END_NAMESPACE
          class Widget : public QWidget
          {
              Q_OBJECT
          public:
              Widget(QWidget *parent = nullptr);
              ~Widget();
          public slots://可以不写
              void handle();
          private:
              Ui::Widget *ui;
              QPushButton* button;
          };
          #endif // WIDGET_H
          

          运行效果:

          sinal_1.gif

          1.3 使用函数名字的方式来自动连接

          双击fromfile中的ui文件

          image.png

          进入图形化构建的界面。

          拖动PushButton控件到中间的界面,右键控件点击转到槽。

          image.png

          然后再点击箭头所☞的内容。

          image.png

          点吉ok后,回到主界面,可以看到这样的界面

          image.png

          这个就是系统自动生成的槽函数,有个这个槽函数我们就不要在显示的写connect函数,下面看演示:

          #include "widget.h"
          #include "ui_widget.h"
          Widget::Widget(QWidget *parent)
              : QWidget(parent)
              , ui(new Ui::Widget)
          {
              ui->setupUi(this);
          }
          Widget::~Widget()
          {
              delete ui;
          }
          void Widget::on_pushButton_clicked()
          {
              ui->pushButton->setText("被点击了~");
          }
          
          #ifndef WIDGET_H
          #define WIDGET_H
          #include 
          QT_BEGIN_NAMESPACE
          namespace Ui { class Widget; }
          QT_END_NAMESPACE
          class Widget : public QWidget
          {
              Q_OBJECT
          public:
              Widget(QWidget *parent = nullptr);
              ~Widget();
          private slots:
              void on_pushButton_clicked();
          private:
              Ui::Widget *ui;
          };
          #endif // WIDGET_H
          

          signal_2.gif

          有人有疑问吗?为什么不用connect就可以关联信号的槽?

          其实也不是没有,只是Qt也自动生成了,而且还有格式要求,打开widget.ui文件,

          不知道怎么打开的话看这篇文章:【Qt】初始项目代码解释-CSDN博客的目录5

          widget.ui:

          image.png

          在这个自动生成的文件中,可以看到一个类似于connect的函数。Qt在调用自动生成的槽函数时就会调用这个函数。

          所有这自动生成的槽函数的名字也是有严格的要求的,一下是要求:

          命名规则on_xxx_sss

          1. 以on开头,中间使用下滑线连接起来。
          2. xxx表示的是对象名,控件的objectName属性。
          3. SSS表示的对应的信号

            注意:

            如果我们通过图形化界面场景控件的话,就推荐这种快速的方式连接函数和槽。

            如果我们是通过代码的方式创建的控件,还是推荐手动的写connect.(你的代码中也没有connectSlotByName)

          2.自定义信号函数

          基础语法

          1. 自定义信号函数必须写到signals下。
          2. 返回值为void,只需要声明,不需要实现。
          3. 可以有参数,也可以发生重载。

          自定义信号函数的本质也就是一个特殊函数而已,这是真的,下面我们会开始演示。

          #include "widget.h"
          #include "ui_widget.h"
          Widget::Widget(QWidget *parent)
              : QWidget(parent)
              , ui(new Ui::Widget)
          {
              ui->setupUi(this);
              connect(this,&Widget::mySignal,this,&Widget::handle);
              //emit mySignal(); 
          }
          Widget::~Widget()
          {
              delete ui;
          }
          void Widget::handle()
          {
              this->setWindowTitle("自定义信号喵~");
          }
          
          #ifndef WIDGET_H
          #define WIDGET_H
          #include 
          QT_BEGIN_NAMESPACE
          namespace Ui { class Widget; }
          QT_END_NAMESPACE
          class Widget : public QWidget
          {
              Q_OBJECT
          public:
              Widget(QWidget *parent = nullptr);
              ~Widget();
          signals:
              void mySignal();
          public slots:
              void handle();
          private:
              Ui::Widget *ui;
          };
          #endif // WIDGET_H
          

          image.png

          运行后发现什么变化都没有呢,这是因为我们没有调用啊。

          我们把注释放开

          #include "widget.h"
          #include "ui_widget.h"
          Widget::Widget(QWidget *parent)
              : QWidget(parent)
              , ui(new Ui::Widget)
          {
              ui->setupUi(this);
              connect(this,&Widget::mySignal,this,&Widget::handle);
              emit mySignal(); 
          }
          Widget::~Widget()
          {
              delete ui;
          }
          void Widget::handle()
          {
              this->setWindowTitle("自定义信号喵~");
          }
          

          image.png

          这样就成功发出信号了,这个信号是不是就相当于函数,调用这个信号就是发出信号。

          再修改修改代码

          #include "widget.h"
          #include "ui_widget.h"
          Widget::Widget(QWidget *parent)
              : QWidget(parent)
              , ui(new Ui::Widget)
          {
              ui->setupUi(this);
              connect(this,&Widget::mySignal,this,&Widget::handle);
          }
          Widget::~Widget()
          {
              delete ui;
          }
          void Widget::handle()
          {
              this->setWindowTitle("自定义信号喵~");
          }
          void Widget::on_pushButton_clicked()
          {
              emit mySignal();
          }
          

          signal_4.gif

          3.知识补充

          3.1 signals和slots

          无论是signals还是slots都是Qt字节扩展出来的关键字,不是C+标准中的语法。

          除此之外Qt里还大量的使用了元编程的技术(根据代码生成代码)

          qmake在构建Qt项目的时候,就会调用专门的扫描器,扫描代码中的关键字,基于关键字自动生成一大堆相关的代码。

          3.2 emit

          emit也就是发射的意思,作用是发出信号,emit是一个空的宏,emit是可选的,不加也不会影响自定义信号函数的发生。

          即便如此,在实际的开发中,还是建议大家,把emit加上,这样的话可读性会变高~

          4. 总结

          在Qt中,允许自定义信号和槽函数。

          自定义槽函数在实际的开发中使用是非常频繁的,不可能不学,自定义信号函数尽管在实际的开发中使用不多,但是还是不得不学啊。

          希望本文对你理解自定义信号和槽函数有帮助~


          往期文章:

          【Qt】初始项目代码解释-CSDN博客

          【Qt】HelloWorld程序-CSDN博客

          【Qt-信号与槽】connect函数的用法-CSDN博客

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码