Qt增加了信号和槽的理念,初学者往往不能明白它的优点,笔者在实际开发之中,对这种设计有了一定的理解,在本文记录一下自己的理解,也希望与大家一同交流。
实际开发中,常常涉及到不止一个窗口,设想这样一个场景,我们新建两个窗口,分别命名为AWidget和BWidget,假如我们有这样一个需求:实现AWidget与BWidget的互相通信,在这种需求之中,试想一下,如果我们不使用信号与槽,我们只能在AWidget中或BWidget中新建另一个窗口的指针变量,这样是可以实现父窗口(也就是拥有另一个窗口指针变量的窗口)与子窗口互相发送数据这一功能的。但是,这种使用指针的方式也会使两者产生强耦合,因为在我们的设计之中,两窗口其实是独立的存在,这种设计也是不安全的,因为父窗口可以任意访问子窗口,更改子窗口的属性,掌握着子窗口的生杀大权,这是极其不合理的,所以我们有必要引入信号和槽。
当使用信号和槽之后,我们无需在两窗口中定义任何的指针,两者不会产生耦合的问题,只需要在main.cpp中定义二者的信号和槽的链接关系,同时在两窗口中定义信号和槽,示例代码如下:
AWidget.h:
#pragma once
#include <QtWidgets\qwidget.h>
#include "ui_AWidget.h"
#include "BWidget.h"
#include <QtWidgets\qmessagebox.h>
class AWidget: public QWidget
{
Q_OBJECT
public:
AWidget(QWidget *parent = 0);
virtual ~AWidget(void);
QString astr;
private:
Ui::Form ui;
private slots:
void btnBClick(QString str);
void btnClick();
signals:
void btnAClick(QString str);
};
AWidget.cpp:
#include "AWidget.h"
AWidget::AWidget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
this->astr = "this is AWidget's data";
//connect(this,SIGNAL(clicked
QObject::connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(btnClick()));
}
AWidget::~AWidget(void)
{
}
void AWidget::btnBClick(QString str){
QMessageBox msg;
msg.setText(str);
msg.exec();
}
void AWidget::btnClick(){
emit btnAClick(this->astr);
}
BWidget.h
#pragma once
#include <QtWidgets\qwidget.h>
#include "ui_BWidget.h"
#include <QtWidgets\qmessagebox.h>
class BWidget: public QWidget
{
Q_OBJECT
public:
BWidget(QWidget *parent = 0);
virtual ~BWidget(void);
QString bstr;
private:
Ui::Form2 ui;
private slots:
void btnAClick(QString str);
void btnClick();
signals:
void btnBClick(QString str);
};
BWidget.cpp
#include "BWidget.h"
BWidget::BWidget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
this->bstr = "this is BWidget's data";
QObject::connect(ui.pushButton_2, SIGNAL(clicked()), this, SLOT(btnClick()));
}
BWidget::~BWidget(void)
{
}
void BWidget::btnAClick(QString str){
QMessageBox msg;
msg.setText(str);
msg.exec();
}
void BWidget::btnClick(){
emit btnBClick(this->bstr);
}
main.cpp:
#include "mainwindow.h"
#include <QtWidgets/QApplication>
#include "AWidget.h"
#include "BWidget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
AWidget *aWidget = new AWidget();
BWidget *bWidget = new BWidget();
QObject::connect(aWidget,SIGNAL(btnAClick(QString)),bWidget,SLOT(btnAClick(QString)));
QObject::connect(bWidget,SIGNAL(btnBClick(QString)),aWidget,SLOT(btnBClick(QString)));
aWidget->show();
bWidget->show();
return a.exec();
}
实现效果:
A向B窗口发送数据:
B向A窗口发送数据: