大家都知道在QT中的信号槽是一种非常重要的方法,这种方法可以使不同的类对象之间进行高效的通信,而且这也是QT区别于其他框架的重要机制之一。这就像MFC和WIN32的消息机制一样。
但是我希望大家以后在使用QT时还是尽量少使用信号槽实现是对象之间的通信。除了一些必须的场合,比如按钮的点击事件、列表框的切换事件等。
为什么这样说呢?
一、在结构上来说,连接信号槽的地方、发射信号的地方、接受信号的地方往往不在一个地方或者离得很近的地方,有时不在一个模块中,这就给代码的阅读带来的很大的困难。当读到发射信号的地方,需要知道这个信号是发给谁的,同理阅读到槽函数时,也需要知道是哪个类对象发射出的哪个信号。当查看完信号槽连接的地方,弄明白发射和接受对象之后,继续在原来的地方阅读代码,往往会打断之前的思路,还有重新花时间来整理思路。就像线程之间的来回切换一下,每次切换都是需要资源成本的。
二、信号槽机制有点像C/C++中的goto句。第一次学C语言的时候,老师就说过,不要使用goto语句,会破坏代码的模块化,但是不明白为什么。随着经验的增加,发现模块与模块之间的高内聚和低耦合是多么的重要!而信号槽这种设计又非常的灵活,可以在不通过类、不用的模块之间发射和接受信号,这也就大大的破坏了模块之间的高内聚性。当开发的模块增多,开发的人员增加后,这种问题就会更加的凸显出来。
那么在QT中如果不使用信号槽在对象之间进行通信,该使用什么方法在不同的类对象之间进行通信呢?
下面看一个例子,先使用信号槽进行通信。
介绍:有两个界面:第一个界面和第二个界面,第一个界面有一个Label,第二个界面有一个编辑框。当点击第一个界面的按钮的时候,弹出第二个界面,当在第二个界面的编辑框编辑完成之后,点击按钮,编辑的内容就会在第一个界面的Label上显示出来。

代码如下:
第一个界面:
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_SignalSlot.h"
class QtGuiSecond;
class SignalSlot : public QMainWindow {
	Q_OBJECT
public:
	SignalSlot(QWidget *parent = Q_NULLPTR);
private:
	void init();
private slots:
	void slotBtn();
	void slotEditStr(QString str);
private:
	Ui::SignalSlotClass ui;
	QtGuiSecond* _guiSecond = nullptr;
};
复制代码#include "SignalSlot.h"
#include "QtGuiSecond.h"
SignalSlot::SignalSlot(QWidget *parent)
	: QMainWindow(parent) {
	ui.setupUi(this);
	init();
}
void SignalSlot::init() {
	connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slotBtn()));
	_guiSecond = new QtGuiSecond;
	connect(_guiSecond, SIGNAL(sigEditStr(QString)), this, SLOT(slotEditStr(QString)));
}
void SignalSlot::slotBtn() {
	_guiSecond->show();
}
void SignalSlot::slotEditStr(QString str) {
	ui.label->setText(str);
}
复制代码第二个界面:
#pragma once
#include <QWidget>
#include "ui_QtGuiSecond.h"
class QtGuiSecond : public QWidget {
	Q_OBJECT
public:
	QtGuiSecond(QWidget *parent = Q_NULLPTR);
	~QtGuiSecond();
private:
	void init();
private slots:
	void slotOK();
signals:
	void sigEditStr(QString);
private:
	Ui::QtGuiSecond ui;
};
复制代码#include "QtGuiSecond.h"
QtGuiSecond::QtGuiSecond(QWidget *parent)
	: QWidget(parent) {
	ui.setupUi(this);
	init();
}
QtGuiSecond::~QtGuiSecond() {
}
void QtGuiSecond::init() {
	connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slotOK()));
}
void QtGuiSecond::slotOK() {
	QString str = ui.lineEdit->text();
	emit sigEditStr(str);
}
复制代码可以看到第二个界面编辑的内容是通过信号槽的方式传过去了。
如果不使用信号槽该怎么传递数据呢?
这就需要我们添加第三个类,也就是接口类,这个类的目的就是为了传递参数的。
#pragma once
#include <QString>
class IEditArg {
public:
	IEditArg();
	~IEditArg();
	virtual void editStr(QString str);
};
复制代码#include "IEditArg.h"
IEditArg::IEditArg() {
}
IEditArg::~IEditArg() {
}
void IEditArg::editStr(QString str) {
}
复制代码然后让第一个界面类继承这个类,并且实现里面的虚函数:
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_SignalSlot.h"
#include "IEditArg.h"
class QtGuiSecond;
class SignalSlot : public QMainWindow, public IEditArg {
	Q_OBJECT
public:
	SignalSlot(QWidget *parent = Q_NULLPTR);
	void editStr(QString str)override;
private:
	void init();
private slots:
	void slotBtn();
private:
	Ui::SignalSlotClass ui;
	QtGuiSecond* _guiSecond = nullptr;
};
复制代码#include "SignalSlot.h"
#include "QtGuiSecond.h"
SignalSlot::SignalSlot(QWidget *parent)
	: QMainWindow(parent) {
	ui.setupUi(this);
	init();
}
void SignalSlot::editStr(QString str) {
	ui.label->setText(str);
}
void SignalSlot::init() {
	connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slotBtn()));
	_guiSecond = new QtGuiSecond;
	_guiSecond->setArgInterface(this);
}
void SignalSlot::slotBtn() {
	_guiSecond->show();
}
复制代码第二个界面类保存这个接口:
#pragma once
#include <QWidget>
#include "ui_QtGuiSecond.h"
class IEditArg;
class QtGuiSecond : public QWidget {
	Q_OBJECT
public:
	QtGuiSecond(QWidget *parent = Q_NULLPTR);
	~QtGuiSecond();
	void setArgInterface(IEditArg* editArg);
private:
	void init();
private slots:
	void slotOK();
private:
	Ui::QtGuiSecond ui;
	IEditArg* _editArg = nullptr;
};
复制代码#include "QtGuiSecond.h"
#include "IEditArg.h"
QtGuiSecond::QtGuiSecond(QWidget *parent)
	: QWidget(parent) {
	ui.setupUi(this);
	init();
}
QtGuiSecond::~QtGuiSecond() {
}
void QtGuiSecond::setArgInterface(IEditArg* editArg) {
	_editArg = editArg;
}
void QtGuiSecond::init() {
	connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slotOK()));
}
void QtGuiSecond::slotOK() {
	QString str = ui.lineEdit->text();
	if (_editArg!=nullptr){
		_editArg->editStr(str);
	}
}
复制代码这样就完成了,虽然代码多了一些但是结构更清晰了!同样也是实现相同的功能呢!有利用了C++的特性。
aaa






![[ 浅谈前端 ] Vue基本使用-一一网](https://www.proyy.com/wp-content/uploads/2024/10/load.gif )















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
