• Qt 一个信号对应多个槽,多个信号对应一个槽的执行顺序


    前言:
    Qt独创的信号槽机制,不仅可以一个信号连接一个槽,而且可以一对多或多对一。
    这其中存在两个最基本的问题:
    1.一个信号对应多个槽时,槽函数的执行顺序是怎样的???
    2.多个信号对应一个槽时,如何在槽函数中判断信号的发出者是谁(来自哪个类的对象)?

    下面对这两种情况分别进行验证:
    实例演示1:对一个信号对应多个槽时,槽函数的执行顺序怎样的?
    mainwindow.h

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3 #include <QMainWindow>
     4 namespace Ui {
     5 class MainWindow;
     6 }
     7 
     8 class MainWindow : public QMainWindow
     9 {
    10     Q_OBJECT
    11 public:
    12     explicit MainWindow(QWidget *parent = 0);
    13     ~MainWindow();
    14 private slots:
    15     void on_pushButton_clicked();
    16     void myslot1(QString); //定义私有槽
    17     void myslot2(QString); //定义私有槽
    18     void myslot3(QString); //定义私有槽
    19 private:
    20     Ui::MainWindow *ui;
    21 };
    22 
    23 //公有继承自 QObject
    24 class MyClass : public QObject
    25 {
    26     Q_OBJECT //声明宏,为了可以使用信号槽机制
    27 public:
    28     MyClass(){}
    29     ~MyClass(){}
    30 signals:
    31     void mysignal(QString); //定义信号(信号全部是公有的)
    32 };
    33 
    34 #endif // MAINWINDOW_H

    mainwindow.cpp

     1 #include "mainwindow.h"
     2 #include "ui_mainwindow.h"
     3 #include <QDebug>
     4 MyClass myclass; //MyClass实例化
     5 
     6 MainWindow::MainWindow(QWidget *parent) :
     7     QMainWindow(parent),
     8     ui(new Ui::MainWindow)
     9 {
    10     ui->setupUi(this);
    11     //信号槽连接(连接顺序:slot2, slot1, slot3)
    12     this->connect(&myclass,SIGNAL(mysignal(QString)), 
    13                   this,SLOT(myslot2(QString)),Qt::UniqueConnection);
    14     this->connect(&myclass,SIGNAL(mysignal(QString)), 
    15                   this,SLOT(myslot1(QString)),Qt::UniqueConnection);
    16     this->connect(&myclass,SIGNAL(mysignal(QString)), 
    17                   this,SLOT(myslot3(QString)),Qt::UniqueConnection);
    18 }
    19 
    20 MainWindow::~MainWindow()
    21 {
    22     delete ui;
    23 }
    24 
    25 void MainWindow::on_pushButton_clicked()
    26 {
    27     //触发信号(推荐在本类触发信号,这里只是为了演示目的)
    28     emit myclass.mysignal("这是一条来自myclass对象的信号");
    29 }
    30 
    31 //槽的实现
    32 void MainWindow::myslot1(QString str)
    33 {
    34     qDebug()<<"slot1:"<<str;
    35 }
    36 void MainWindow::myslot2(QString str)
    37 {
    38     qDebug()<<"slot2:"<<str;
    39 }
    40 void MainWindow::myslot3(QString str)
    41 {
    42     qDebug()<<"slot3:"<<str;
    43 }

    槽函数的执行顺序和信号槽连接的顺序一致,运行结果如下:

    实例演示2:多个信号对应一个槽时,如何在槽函数中判断发出者?

    原理:首先利用 QObject::setObjectName(const QString&) 方法设置信号发出者的对象名称,
    然后在槽函数中利用 QObject::sender()->objectName() 方法获取信号发出者的对象名称。
    mainwindow.h

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3 
     4 #include <QMainWindow>
     5 
     6 namespace Ui {
     7 class MainWindow;
     8 }
     9 
    10 class MainWindow : public QMainWindow
    11 {
    12     Q_OBJECT
    13 public:
    14     explicit MainWindow(QWidget *parent = 0);
    15     ~MainWindow();
    16 private slots:
    17     void on_pushButton_clicked();
    18     void myslot(QString); //定义私有槽
    19 private:
    20     Ui::MainWindow *ui;
    21 };
    22 
    23 //公有继承自 QObject
    24 class MyClass : public QObject
    25 {
    26     Q_OBJECT //声明宏,为了可以使用信号槽机制
    27 public:
    28     MyClass(){}
    29     ~MyClass(){}
    30 signals:
    31     void mysignal(QString); //定义信号(信号全部是公有的)
    32 };
    33 #endif // MAINWINDOW_H

    mainwindow.cpp

     1 #include "mainwindow.h"
     2 #include "ui_mainwindow.h"
     3 #include <QDebug>
     4 MyClass myclass1; //MyClass实例化1
     5 MyClass myclass2; //MyClass实例化2
     6 MyClass myclass3; //MyClass实例化3
     7 
     8 MainWindow::MainWindow(QWidget *parent) :
     9     QMainWindow(parent),
    10     ui(new Ui::MainWindow)
    11 {
    12     ui->setupUi(this);
    13     myclass1.setObjectName("myclass1");
    14     myclass2.setObjectName("myclass2");
    15     myclass3.setObjectName("myclass3");
    16     //信号槽连接
    17     this->connect(&myclass1,SIGNAL(mysignal(QString)), 
    18                   this,SLOT(myslot(QString)),Qt::UniqueConnection);
    19     this->connect(&myclass2,SIGNAL(mysignal(QString)), 
    20                   this,SLOT(myslot(QString)),Qt::UniqueConnection);
    21     this->connect(&myclass3,SIGNAL(mysignal(QString)), 
    22                   this,SLOT(myslot(QString)),Qt::UniqueConnection);
    23 }
    24 
    25 MainWindow::~MainWindow()
    26 {
    27     delete ui;
    28 }
    29 
    30 void MainWindow::on_pushButton_clicked()
    31 {
    32     //触发信号(推荐在本类触发信号,这里只是为了演示目的)
    33     emit myclass1.mysignal("这是一条测试信号");
    34     emit myclass2.mysignal("这是一条测试信号");
    35     emit myclass3.mysignal("这是一条测试信号");
    36 }
    37 
    38 //槽的实现
    39 void MainWindow::myslot(QString str)
    40 {
    41     qDebug()<<"from "<<sender()->objectName()<<""<<str;
    42 }

    运行结果如下:

    在这里插入图片描述

  • 相关阅读:
    SpringCloud初体验:四、API GateWay 服务网关
    SpringCloud初体验:三、Feign 服务间调用(FeignClient)、负载均衡(Ribbon)、容错/降级处理(Hystrix)
    SpringCloud初体验:二、Config 统一配置管理中心
    SpringCloud初体验:一、Eureka 服务的注册与发现
    PHP 通过实现 Iterator(迭代器)接口来读取大文件文本
    SpringCloud初体验:前言
    springboot利用MockMvc测试controller控制器
    vue通过(NGINX)部署在子目录或者二级目录实践
    PHP 设计模式 原型模式(Prototype)之深/浅拷贝
    PHPstorm配置PHPunit对composer引入的php代码进行单元测试
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14636939.html
Copyright © 2020-2023  润新知