使用mainwindow构建
Signal
在Qt中,信号(signals)是特殊的成员函数,它们用于对象间的通信,并且有一些特殊的规则:
-
没有返回值:信号不能有任何返回值。在您的例子中,
void signalOne()
看起来是满足这个条件的,因为它没有返回值。但是,重要的是要注意信号的实现(即函数体)通常是不需要的,也是不允许的。信号的实现由Qt的元对象系统(通过MOC)自动处理。 -
不能有函数体:在Qt中,信号通常没有函数体。它们被声明为没有实现的函数原型,MOC工具会处理这些声明并生成必要的代码来连接信号和槽。然而,在您的代码片段中,
signalOne()
有一个函数体{ qDebug("wanted"); }
,这是不允许的。 -
使用
Q_OBJECT
宏:包含信号的类必须继承自QObject
(或其子类),并且必须在类的私有部分包含Q_OBJECT
宏。这个宏为类启用了Qt的元对象系统,包括信号和槽的机制。
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<QPushButton>
#include<QApplication>
#include<QMessageBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "wanted.h"
#include "foods.h"
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
Foods *foods1;
Wanted *wanted1;
void emitSingal();//声明发射信号函数
};
#endif // MAINWINDOW_H
//mainwindoww.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
foods1 = new Foods(this);
wanted1 = new Wanted();
QObject::connect(wanted1, &Wanted::signalOne, foods1, &Foods::slotOne);//连接信号和槽函数
emitSingal();//使用函数发射信号
}
void MainWindow::emitSingal(){
emit wanted1->signalOne();
}//发射信号函数的具体实现
MainWindow::~MainWindow()
{
delete ui;
}
//wanted.h
#ifndef WANTED_H
#define WANTED_H
#include <QMainWindow>
#include <QObject>
#include <QWidget>
class Wanted:public QObject
{
Q_OBJECT
public:
Wanted(QMainWindow *parent = nullptr);
~Wanted();
signals:
void signalOne();//声明了信号一
};
#endif // WANTED_H
//wanted.cpp
#include "wanted.h"
Wanted::Wanted(QMainWindow *parent) {
}//无需具体实现信号函数
Wanted::~Wanted()
{
}
//foods.h
#ifndef FOODS_H
#define FOODS_H
#include <QMainWindow>
#include <QObject>
#include <QWidget>
class Foods:public QObject
{
Q_OBJECT
public:
Foods(QMainWindow *parent = nullptr);
~Foods();
void slotOne();//定义了slotOne槽函数,在某些低版本Qt中,需要先声明public slots:
};
#endif // FOODS_H
//foods.cpp
#include "foods.h"
Foods::Foods(QMainWindow *parent) {
}//QMainWindow作为父类,而不是QWidget
Foods::~Foods()
{}
void Foods::slotOne(){
qDebug("foods");
}//槽函数的具体实现
输出结果
重载函数的情况
//wanted.h
signals:
void signalOne();
void signalOne(QString a);//新增了一个重载函数
//foods.h
void slotOne();
void slotOne(QString a);//槽函数与信号函数同步,也声明一个返回值相同,形参相同的重载函数
//foods.cpp
void Foods::slotOne(){
qDebug("foods");
}
void Foods::slotOne(QString a){
qDebug()<< a;
}//槽重载函数的具体实现
//mainwindow.cpp
//
foods1 = new Foods(this);
wanted1 = new Wanted();
void(Wanted:: *wanten1Signal)(QString)=&Wanted::signalOne;
void(Foods:: *foodsSignal)(QString)=&Foods::slotOne;//当信号函数和槽函数有了重载函数以后,就要创建函数指针明确指向的是哪一个函数,否则原先的QObject::connect(wanted1, &Wanted::signalOne, foods1, &Foods::slotOne);编译会不通过
QObject::connect(wanted1, wanten1Signal, foods1, foodsSignal);
emitSingal();
}
void MainWindow::emitSingal(){
emit wanted1->signalOne("coffee");
}
输出结果:
可以看到这里输出的不是字符串原本的内容,而是在原有的基础上加上了双引号
要解决这个问题,把qDebug()<< a改为qDebug()<< a.toUtf8().data(),既先把a转换成QByteArray再转换成char *