Qt--信号与槽机制

Posted herr_edoc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt--信号与槽机制相关的知识,希望对你有一定的参考价值。

一、什么是信号槽机制

       信号槽机制是Qt的核心特性,是对C/C++的拓展,应用于对象与对象之间的通信。信号槽的处理依赖于moc(Meta Object Compiler)工具。

       信号槽机制很好地完成了界面操作的响应,类似于MFC和matlab GUI中的callback函数。信号与槽会通过connect函数进行连接,信号会在某种情况或者动作下由某个对象发射,连接了该信号的槽会接收到该信号,然后执行相应的操作。

二、信号槽机制的连接方式

       比较常用的连接方式是,对象A发射信号,对象B的槽函数接收信号做出响应。函数原型:QMetaObject::Connection connect (const QObject *, const char*, const QObject*, const char*, Qt::ConnectionType)。一般只使用前面的四个参数,即connect(sender, signal, receiver, slot)。sender发送signal,然后receiver的slot接收信号。

       以下举个小例子,点击按钮关闭窗口。

       创建Qt Widgets Application,基于QMainWindow类,不包含ui文件。修改MainWindow构造函数如下:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)

    QPushButton *btn1 = new QPushButton(tr("Close"));//创建一个按钮控件
    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addWidget(btn1, 1, Qt::AlignCenter);//将按钮添加到布局管理器中
    QWidget *mainWidget = new QWidget(this);
    mainWidget->setLayout(mainLayout);
    this->setCentralWidget(mainWidget);//将新建的mainWidget作为MainWindow的主widget

    connect(btn1, SIGNAL(clicked(bool)), this, SLOT(close()));//按钮btn1被点击时发射信号,窗口MainWindow接收到信号时调用close()函数,关闭窗口。

       程序运行结果如下:

                                                                                                       

      点击Close按钮,窗口关闭。

      信号与槽除了以上介绍的最普遍的连接方式外,还有以下常见的连接方式:

      (1)一个信号与多个槽连接

      (2)一个槽与多个信号连接

      其中,一个信号与多个槽连接,当该信号发射时,与其连接的槽会一一执行,但是执行的顺序是随机的,不能人为指定槽的执行顺序。

      当想断开信号与槽的连接时,可以使用以下方法:

      (1)断开与对象A相关的所有连接

       disconnect(ObjectA, 0, 0, 0);

      (2)断开与信号A相关的所有连接

       disconnect(ObjectA, SignalA, 0, 0);

      (3)断开对象A和对象B的连接

       disconnect(ObjectA, 0, ObjectB, 0);

三、自定义信号和槽

       Qt信号槽机制除了可以使用对象自带的信号和槽之外,还可以自定义信号函数和槽函数,为界面设计提供了方便和灵活性。

       为了使用自定义的信号和槽,包含自定义信号和槽的类必须继承于QObject类或者其子类,包括Q_OBJEDT宏定义。Q_OBJECT宏必须出现在类定义的第一行,它的展开用于启动元对象的特性,其中就包括信号槽特性。

       自定义信号:自定义信号写在头文件声明中,用Signals关键字来指出进入信号函数声明区。信号函数的声明形式上和普通函数一样,但是信号函数没有返回值(即返回值为void),有参数,但是参数不能有缺省参数。另外,信号函数没有函数体定义。

       自定义槽:自定义槽同样写在头文件声明中,用Slots关键字来指出进入槽函数声明区。槽函数和类普通的成员函数一样有声明和定义,但是同样不能有缺省参数。槽函数可以加private、protected、public来限制与之相连接的信号。

       以下举个自定义信号和槽的例子:

       创建Qt Widgets Application,基于QMainWindow类,不包含ui文件。MainWindow类添加槽函数showWarning(QStirng)。工程添加C++类Warning类,Warning类继承于QObject,包含warning信号。

       mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>


class MainWindow : public QMainWindow

    Q_OBJECT

public slots:
    void showWarning(QString message);

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
;

#endif // MAINWINDOW_H

       mainwindow.cpp

#include "mainwindow.h"
#include <QMessageBox>
#include "warning.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)

    Warning myWarning(QString("It is too hot!"));
    connect(&myWarning, SIGNAL(warning(QString)), this, SLOT(showWarning(QString)));//将Warning类的信号warning(QString)与MainWindow的槽showWarning(QString)相连接
    myWarning.sendWarning();//发射信号


void MainWindow::showWarning(QString message)

    QMessageBox::information(this, tr("QMessageBox::information()"), message);


MainWindow::~MainWindow()


       warning.h

#ifndef WARNING_H
#define WARNING_H
#include <QObject>

class Warning : public QObject

    Q_OBJECT
private:
    QString message;

public:
    Warning(QString myMessage);
    void sendWarning()
    
        emit warning(message);
    

signals:\\
    void warning(QString message);
;

#endif // WARNING_H

       warning.cpp

#include "warning.h"

Warning::Warning(QString myMessage)

    message = myMessage;

       程序运行结果如下:

                                                                                                              


四、信号槽机制的优点简述

       1. 类型安全

       需要关联的信号和槽的签名必须是等同的,即信号函数的参数类型和个数和槽函数的参数类型和个数应该是相同的,不过槽函数的参数个数可以少于信号函数的参数个数,但是少的参数必须是最后的参数。如果信号函数和槽函数的签名不一致,则编译会出错。

       2. 松耦合

       Qt提供的信号槽机制,使得信号的发送者不需要知道接收槽属于哪个对象,而只需要负责在适当的时候或情况下发送信号;而接收信号的对象同样不需要知道有哪些信号关联了自己的槽函数。connect函数决定了哪些信号与哪些槽相连接。

       3. 灵活性

       Qt提供的信号槽机制允许用户自定义信号和槽,而且信号与槽的连接为多对多连接,即一个信号可以连接多个槽,一个槽同样可以连接多个信号,这使得界面设计更加方便灵活。

       本文参考了陆文周主编的《Qt 5--开发及实例》(第2版)以及以下网址:

       1. QT的信号与槽机制介绍点击打开链接

       2. Qt学习之路2:信号槽 | DevBean Tech World点击打开链接

       其中“QT的信号与槽机制介绍”是一篇很不错的文章,包含很多细节问题,例如信号和槽函数在定义时需要注意的细节。

以上是关于Qt--信号与槽机制的主要内容,如果未能解决你的问题,请参考以下文章

QT开发(十三)——QT信号与槽机制

Qt的信号槽机制可以保障线程安全吗

Qt--信号与槽机制

QT的信号槽机制

androidUI卡顿原理分析及Vsync信号机制

Qt信号与槽自动关联机制