Qt 信号与槽机制原理

目录

信号与槽机制原理

信号与槽机制连接方式

信号与槽应用实战


信号与槽机制原理

信号(signal):所谓信号槽(观察者模式),信号本质是事件。信号展现方式就是函数。当某一个事件发生以后,则发出一个信号(signal)。

槽(slot):就是对信号响应的函数,槽就是一个函数。槽函数与普通函数区别:槽函数可以与一个信号关联,当信号被发射的时候,关联的槽函数被自动执行处理。信号与槽关联时使用QObject::connect()函数进行实现。

Qt 信号与槽机制原理_第1张图片

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

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

槽函数可以使用 public slots/protected slots/private slots修饰。signals 和 slots 是Qt开发当中在C++语言基础之上拓展的关键词,专门用于指明信号函数和槽函数。

QObject::connect()函数

QObject::connect(const QObject *sender,const char *signal,const QObject *receiver,const char *method)

函数参数:

  1. sender:发出信号的对象
  2. signal:sender对象的信号
  3. receiver:信号接收者
  4. method:receiver对象的槽函数,当检测到 sender 信号,receiver 对象调用 method 方法。

信号与槽机制连接方式

一个信号可以跟另一个信号相连:

connect(object1,SIGNAL(signal),object2,SIGNAL(signal2));

同一个信号可以跟多个槽相连

connect(object1,SIGNAL(signal2),object2,SIGNAL(slot2));
connect(object1,SIGNAL(signal2),object3,SIGNAL(slot1));

同一个槽可以响应多个信号

connect(object1,SIGNAL(signal2),object2,SIGNAL(slot2));
connect(object3,SIGNAL(signal2),object2,SIGNAL(slot2));

常用连接方式

connect(object1,SIGNAL(signal),object2,SLOT(slot));

信号与槽机制优势:松散耦合;一个类要支持信号和槽,就必须从QObject或QObject的子类继承,Qt信号和槽机制不支持对模板的使用。

信号与槽机制效率:增强对象之间通信的灵活性,但是也会损失一些性能。通过传递一个信号来调用槽函数将会比直接调用非虚函数运行速度慢,主要原因:

  • 多线程的时候,信号可能需要排队等待
  • 编组/解组传递的参数
  • 安全地遍历所有地关联
  • 需要定位接收信号的对象

信号与槽应用实战

创建一个对话框程序,修改窗口标题

#include "dialog.h"

#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;

    // 修改应用程序窗口的名称
    w.setWindowTitle("计算圆球体积");

    w.show();
    return a.exec();
}

dialog.h文件

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

private:
    Ui::Dialog *ui;

private:
    QLabel *lab1,*lab2;
    QLineEdit *lEdit;
    QPushButton *pbt;

private slots:
    void CalcBallVolume();

};
#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include 

const static double PI=3.1415;

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);

    // 创建第1个标签(提示用户输入圆球的半径)
    lab1=new QLabel(this);
    lab1->setText(tr("请输入圆球的半径:"));

    // 创建第2个标签(专门用来显示计算圆球体积的结果)
    lab2=new QLabel(this);

    // 创建一个编辑框控件(专门用于接收用户的输入圆球半径的值)
    lEdit=new QLineEdit(this);

    // 创建命令按钮
    pbt=new QPushButton(this);
    pbt->setText(tr("计算圆球体积"));

    // 表格布局
    QGridLayout *mLay=new QGridLayout(this);
    mLay->addWidget(lab1,0,0);
    mLay->addWidget(lEdit,0,1);
    mLay->addWidget(lab2,1,0);
    mLay->addWidget(pbt,1,1);

    connect(lEdit,SIGNAL(textChanged(QString)),this,SLOT(CalcBallVolume()));
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::CalcBallVolume() // 槽函数计算圆球的体积
{
    bool isLoop;
    QString tempStr;
    QString valueStr=lEdit->text();

    int valueInt=valueStr.toInt(&isLoop);
    double dVSum=4.0/3.0*PI*valueInt*valueInt*valueInt;
    lab2->setText(tempStr.setNum(dVSum));
}

通过使用tr()函数,可以实现多语言支持,使得程序可以根据用户的语言设置,显示对应语言的界面文本。这样用户无论使用何种语言,都能够更好地理解和操作程序。

connect(lEdit,SIGNAL(textChanged(QString)),this,SLOT(CalcBallVolume()));

  • connect()函数用于在Qt中连接信号和槽,以实现对象之间的通信和交互。
  • 在这个例子中,connect()函数将一个信号和一个槽连接在一起。
  • 信号通过对象lEdit的textChanged(QString)信号来触发。textChanged(QString)信号表示当lEdit对象的文本内容发生变化时发出的信号。
  • 槽通过当前对象(this)的CalcBallVolume()槽函数来接收信号。
  • CalcBallVolume()是一个槽函数,它会在lEdit的文本内容发生变化时被调用。

通过这个连接语句,当lEdit对象的文本内容发生变化时,会自动触发CalcBallVolume()槽函数的执行。

你可能感兴趣的:(QT,qt,开发语言)