当前位置:   article > 正文

Qt之信号与槽

Qt之信号与槽

槽的本质:对信号响应的函数。

信号函数和槽函数通常位于某个类中,和普通的成员函数相⽐,它们的特别之处在于:
信号函数⽤ signals 关键字修饰,槽函数⽤ public slots、protected slots 或者 private slots 修饰。signals 和 slots 是 Qt 在 C++ 的基础上扩展的关键字,专⻔⽤来指明信号函数和槽数;
信号函数只需要声明,不需要定义(实现),⽽槽函数需要定义(实现)。
信号和槽的使用
在 Qt 中,QObject 类提供了⼀个静态成员函数 connect() ,该函数专⻔⽤来关联指定的信号函数和槽函数。

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,通常不需要⼿动设定。
自动生成槽函数

通过在UI中创建控件,鼠标右键(找到   【转到槽】-> 【选择对应的信号】)来快速生成槽函数。

该方法对应的操作如下:

(1)  在 "widget.h" 头⽂件中⾃动添加槽函数的声明;
说明:
⾃动⽣成槽函数的名称有⼀定的规则。槽函数的命名规则为:on_XXX_SSS,其中:
1、以 " on " 开头,中间使⽤下划线连接起来;
2、" XXX " 表⽰的是对象名(控件的 objectName 属性)。
3、" SSS " 表⽰的是对应的信号。
如:" on_pushButton_clicked() " ,pushButton 代表的是对象名,clicked 是对应的信号。

(2)  在 "widget.cpp" 中⾃动⽣成槽函数定义.  

自定义信号和槽
1、⾃定义信号函数书写规范
(1)⾃定义信号函数必须写到 "signals" 下;
(2)返回值为 void,只需要声明,不需要实现;
(3)可以有参数,也可以发⽣重载;
2、⾃定义槽函数书写规范
(1)早期的 Qt 版本要求槽函数必须写到 "public slots" 下,但是现在⾼级版本的 Qt 允许写到类的 "public" 作⽤域中或者全局下;
(2)返回值为 void,需要声明,也需要实现;
(3)可以有参数,可以发⽣重载;
带参数的信号和槽
Qt 的信号和槽也⽀持带有参数, 同时也可以⽀持重载.
此处我们要求, 信号函数的参数列表要和对应连接的槽函数参数列表⼀致.
此时信号触发, 调⽤到槽函数的时候, 信号函数中的实参就能够被传递到槽函数的形参当中.
代码示例
widget.h
  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. QT_BEGIN_NAMESPACE
  5. namespace Ui { class Widget; }
  6. QT_END_NAMESPACE
  7. class Widget : public QWidget
  8. {
  9. Q_OBJECT
  10. public:
  11. Widget(QWidget *parent = nullptr);
  12. ~Widget();
  13. signals:
  14. void mySignal(const QString& text,const QString& text2);
  15. public:
  16. void handleSignal(const QString& text);
  17. private slots:
  18. void on_pushButton_clicked();
  19. void on_pushButton_2_clicked();
  20. private:
  21. Ui::Widget *ui;
  22. };
  23. #endif // WIDGET_H

widget.cpp

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. Widget::Widget(QWidget *parent)
  4. : QWidget(parent)
  5. , ui(new Ui::Widget)
  6. {
  7. ui->setupUi(this);
  8. connect(this,&Widget::mySignal,this,&Widget::handleSignal);
  9. // // 发射出自定义的信号
  10. // //发送信号的操作,也可以在任意合适的代码中,不一定非得在构造函数里
  11. // emit mySignal();
  12. }
  13. Widget::~Widget()
  14. {
  15. delete ui;
  16. }
  17. void Widget::handleSignal(const QString& text)
  18. {
  19. // this->setWindowTitle("处理自定义信号");
  20. this->setWindowTitle(text);
  21. }
  22. void Widget::on_pushButton_clicked()
  23. {
  24. // 发射出自定义的信号
  25. //发送信号的操作,也可以在任意合适的代码中,不一定非得在构造函数里
  26. // emit mySignal();
  27. emit mySignal("把标题设置为标题1","");
  28. }
  29. void Widget::on_pushButton_2_clicked()
  30. {
  31. emit mySignal("把标题设置为标题2","");
  32. }

结果演示:

信号与槽的连接方式
一对一

一对多

多对一

代码演示(一对多,多对一)

widget.h

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. QT_BEGIN_NAMESPACE
  5. namespace Ui { class Widget; }
  6. QT_END_NAMESPACE
  7. class Widget : public QWidget
  8. {
  9. Q_OBJECT
  10. public:
  11. Widget(QWidget *parent = nullptr);
  12. ~Widget();
  13. signals:
  14. void mySignal1();
  15. void mySignal2();
  16. void mySignal3();
  17. public slots:
  18. void mySlot1();
  19. void mySlot2();
  20. void mySlot3();
  21. private:
  22. Ui::Widget *ui;
  23. };
  24. #endif // WIDGET_H

widget.cpp

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. #include <QDebug>
  4. Widget::Widget(QWidget *parent)
  5. : QWidget(parent)
  6. , ui(new Ui::Widget)
  7. {
  8. ui->setupUi(this);
  9. connect(this,&Widget::mySignal1,this,&Widget::mySlot1);
  10. connect(this,&Widget::mySignal1,this,&Widget::mySlot2);
  11. connect(this,&Widget::mySignal2,this,&Widget::mySlot1);
  12. connect(this,&Widget::mySignal2,this,&Widget::mySlot3);
  13. }
  14. Widget::~Widget()
  15. {
  16. delete ui;
  17. }
  18. void Widget::mySlot1()
  19. {
  20. qDebug()<<"mySlot1";
  21. }
  22. void Widget::mySlot2()
  23. {
  24. qDebug()<<"mySlot2";
  25. }
  26. void Widget::mySlot3()
  27. {
  28. qDebug()<<"mySlot3";
  29. }
信号与槽的断开
使⽤ disconnect 即可完成断开.
disconnect 的⽤法和 connect 基本⼀致
代码演示
widget.h
  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. QT_BEGIN_NAMESPACE
  5. namespace Ui { class Widget; }
  6. QT_END_NAMESPACE
  7. class Widget : public QWidget
  8. {
  9. Q_OBJECT
  10. public:
  11. Widget(QWidget *parent = nullptr);
  12. ~Widget();
  13. void handleClick();
  14. void handleClick2();
  15. //private slots:
  16. // void on_pushButton_clicked();
  17. private slots:
  18. void on_pushButton_2_clicked();
  19. private:
  20. Ui::Widget *ui;
  21. };
  22. #endif // WIDGET_H

widget.hpp

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. #include <QDebug>
  4. Widget::Widget(QWidget *parent)
  5. : QWidget(parent)
  6. , ui(new Ui::Widget)
  7. {
  8. ui->setupUi(this);
  9. connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick);
  10. }
  11. Widget::~Widget()
  12. {
  13. delete ui;
  14. }
  15. void Widget::handleClick()
  16. {
  17. this->setWindowTitle("修改窗口的标题");
  18. qDebug()<<"handleClick";
  19. }
  20. void Widget::handleClick2()
  21. {
  22. this->setWindowTitle("修改窗口的标题2");
  23. qDebug()<<"handleClick2";
  24. }
  25. //void Widget::on_pushButton_clicked()
  26. //{
  27. //}
  28. void Widget::on_pushButton_2_clicked()
  29. {
  30. //先断开 pushButton 原来的信号槽
  31. disconnect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick);
  32. // connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick2);
  33. }
使用lambda定义槽函数

widget.cpp

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. #include <QPushButton>
  4. #include <QDebug>
  5. Widget::Widget(QWidget *parent)
  6. : QWidget(parent)
  7. , ui(new Ui::Widget)
  8. {
  9. ui->setupUi(this);
  10. QPushButton* button=new QPushButton(this);
  11. button->setText("按钮");
  12. button->move(200,200);
  13. connect(button,&QPushButton::clicked,this,[=](){
  14. qDebug()<<"lambda 被执行了!";
  15. button->move(300,300);
  16. this->move(100,100);
  17. });
  18. }
  19. Widget::~Widget()
  20. {
  21. delete ui;
  22. }

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/535459
推荐阅读
相关标签
  

闽ICP备14008679号