目录
信号与槽机制原理
信号与槽机制连接方式
信号与槽应用实战
信号(signal):所谓信号槽(观察者模式),信号本质是事件。信号展现方式就是函数。当某一个事件发生以后,则发出一个信号(signal)。
槽(slot):就是对信号响应的函数,槽就是一个函数。槽函数与普通函数区别:槽函数可以与一个信号关联,当信号被发射的时候,关联的槽函数被自动执行处理。信号与槽关联时使用QObject::connect()函数进行实现。
信号函数只需要声明(不需要定义(实现)),而槽函数需要定义(实现)。
信号和槽机制底层是通过函数之间进行相互调用实现的。每个信号都可以用函数来表示,成为信号函数;每个槽也可以用函数表示,称为槽函数。
槽函数可以使用 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)
函数参数:
一个信号可以跟另一个信号相连:
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()));
通过这个连接语句,当lEdit对象的文本内容发生变化时,会自动触发CalcBallVolume()槽函数的执行。