需求:
下班后,小明说请小红吃好吃的,随便吃,吃啥买啥
无参:小红没有提出吃啥
有参:小红提出自己想吃的东西,吃啥取决于一时兴起(emit触发)
思路:
1,定义一个button和一个label,button点击表示下班
2,定义两个类,小明和小红类,小红类里面为signals信号,小明类里面为slots槽函数
3,小红类和小明类均包括有参和无参两种情况,因为小红有可能没有自己的想法,也有可能有自己的主意
一、项目创建
项目名称:Afterwork
新建xiaoming
和xiaohong
两个QtWidgetsClass
直接下一步就行
最终的目录结构
二、UI布局
两个button,一个label
第一个button负责触发下班信号(无参),因为小红没有想法
第二个button负责触发下班信号(有参),小红有想法,想吃啥取决于emit触发这个信号是有参的还是无参数的
label负责显示一下信息,emit在Afterwork.h中定义,在Afterwork.cpp中实现
三、signals信号函数
xiaohong为信号方,故需要进行定义相应的signals信号,需要告诉xiaoming,自己想吃啥
有两种情况:
一种是无参,不知道想吃啥,没主意
另一种是有参,有想法,但需要看emit给这个信号发送的参数food
emit在Afterwork.h中定义,在Afterwork.cpp中实现
1,xiaohong.h
对信号函数进行声明,信号只声明不实现
#include "ui_xiaohong.h"
class xiaohong : public QMainWindow
{
Q_OBJECT
public:
xiaohong(QWidget *parent = nullptr);
~xiaohong();
signals:
void eat();
void eat(QString food);
private:
Ui::xiaohongClass ui;
};
2,xiaohong.cpp
不需要改变
#include "xiaohong.h"
#include <QDebug>
xiaohong::xiaohong(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
xiaohong::~xiaohong()
{}
四、slots槽函数
1,xiaoming.h
xiaoming为信号接收方,有两种信号,有可能有想法(取决于emit触发xiaohong的信号所携带的参数food),也有可能没有想法,此时需要对应两个槽函数进行接收。槽函数既要声明也要实现
因为这是头文件,这里只需要声明,实现的话在.cpp文件中进行实现
#pragma once
#include <QMainWindow>
#include "ui_xiaoming.h"
class xiaoming : public QMainWindow
{
Q_OBJECT
public:
xiaoming(QWidget *parent = nullptr);
~xiaoming();
public slots:
void buy();
void buy(QString foodName);
private:
Ui::xiaomingClass ui;
};
2,xiaoming.cpp
若xiaohong没想法,调用无参的buy函数,输出She doesn’t know what to eat, and I don’t know what to buy.
若xiaohong有想法,就调用有参的buy函数,形参为QString food,输出qDebug() << “Buy her a " << food.toUtf8().data()<<”.";
Qt里面输出用的是qDebug(),因为在Qt在输出变量的时候会有双引号,需要将其去掉,通过toUtf8().data()
#include "xiaoming.h"
#include <QDebug>
xiaoming::xiaoming(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
xiaoming::~xiaoming()
{}
//实现
void xiaoming::buy()
{
qDebug() << "She doesn't know what to eat, and I don't know what to buy.";
}
void xiaoming::buy(QString food)
{
//QString 自带双引号
//先转QByteArray(使用toUtf8())再转char*(使用data())
qDebug() << "Buy her a " << food.toUtf8().data()<<".";
}
五、Afterwork.h
xiaoming* xm;
、xiaohong* xh;
之所以在Afterwork类里面定义xiaoming和xiaohong类的对象xm和xh,是因为这里面的两个用于emit触发xiaohong的信号的函数(workoff_n和workoff_y)是private类的,emit触发信号的时候需要对类对象进行发送,故在Afterwork类里面进行了定义xiaoming和xiaohong类的对象xm和xh
void workoff_n();
用于emit触发信号(无参数),触发xiaohong,给xiaohong说下班了,此时的xiaohong没想法吃啥
void workoff_y();
用于emit信号(有参数food),激发xiaohong,给xiaohong说下班了,此时的xiaohong想吃food,这里的food是形参,可以自定义
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_Afterwork.h"
#include "xiaoming.h"
#include "xiaohong.h"
class Afterwork : public QMainWindow
{
Q_OBJECT
public:
Afterwork(QWidget *parent = nullptr);
~Afterwork();
private:
Ui::AfterworkClass ui;
xiaoming* xm;
xiaohong* xh;
void workoff_n();
void workoff_y();
};
六、Afterwork.cpp
无参和有参的emit触发信号函数的实现
无参emit触发信号函数workoff_n() ,信号发出者xiaohong,emit触发xiaohong的不知道想吃啥的信号
ui上的label控件显示She doesn’t know what to eat.
有参(hamburger)emit触发信号函数workoff_y() ,信号发出者xiaohong,emit触发xiaohong的想吃hamburger的信号,这里的hamburger是字符串,可以进行自定义
ui上的label控件显示She wants a hamburger.
void Afterwork::workoff_n()
{
emit xh->eat();
ui.label->setText("She doesn't know what to eat.");
}
void Afterwork::workoff_y()
{
emit xh->eat("hamburger");
ui.label->setText("She wants a hamburger.");
}
1,无参
void(xiaoming:: * xmSignal_n)(void) = &xiaoming::buy;
void(xiaohong:: * xhSignal_n)(void) = &xiaohong::eat;
&为地址,指针可以指向地址,函数指针可以指向函数地址
(void) 这里是无参,对应的是无参的 &xiaoming::buy 和无参的 &xiaohong::eat
关联
connect(xh, xhSignal_n, xm, xmSignal_n);
信号发出者为:xiaohong类对象xh
发送的信号为:xhSignal_n,xiaohong的没有想法的eat,即无参信号
信号接收者为:xiaoming类对象xm
信号的处理(槽函数):xmSignal_n,xiaoming面对xiaohong无想法(无参)的eat信号所采用的无想法(无参)的buy槽函数相应
再次关联
connect(ui.pushButton, &QPushButton::clicked, this, &Afterwork::workoff_n);
信号发出者为:ui.pushButton,也就是下班(没想法)
这个按键
发送的信号为:&QPushButton::clicked,按键被点击
信号接收者为:this当前这个QWidget
信号的处理(槽函数):&Afterwork::workoff_n,用于emit触发函数对xiaohong这个信号进行触发,触发的时候无参数传递
2,有参
void(xiaohong:: * xhSignal_y)(QString) = &xiaohong::eat;
void(xiaoming:: * xmSignal_y)(QString) = &xiaoming::buy;
&为地址,指针可以指向地址,函数指针可以指向函数地址
(QString) 这里是有参,且参数是QString类型,对应的是有参且参数类型为QString的 &xiaoming::buy 和有参且参数类型为QString的 &xiaohong::eat
关联
connect(xh, xhSignal_y, xm, xmSignal_y);
信号发出者为:xiaohong类对象xh
发送的信号为:xhSignal_y,xiaohong的有想法(有food形参)的eat
信号接收者为:xiaoming类对象xm
信号的处理(槽函数):xmSignal_y,xiaoming面对xiaohong有想法(有参,但取决于emit触发传入的food形参)的eat信号所采用的有想法的buy槽函数相应
再次关联
connect(ui.pushButton_2, &QPushButton::clicked, this, &Afterwork::workoff_y);
信号发出者为:ui.pushButton_2,也就是下班(有想法)
这个按键
发送的信号为:&QPushButton::clicked,按键被点击
信号接收者为:this当前这个QWidget
信号的处理(槽函数):&Afterwork::workoff_y,用于emit触发函数对xiaohong这个信号进行触发,触发的时候带有food参数
#include "Afterwork.h"
#include <QDebug>
#include "xiaohong.h"
#include "xiaoming.h"
Afterwork::Afterwork(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
this->xh = new xiaohong(this);
this->xm = new xiaoming(this);
//无参数
void(xiaoming:: * xmSignal_n)(void) = &xiaoming::buy;
void(xiaohong:: * xhSignal_n)(void) = &xiaohong::eat;
connect(xh, xhSignal_n, xm, xmSignal_n);
connect(ui.pushButton, &QPushButton::clicked, this, &Afterwork::workoff_n);
//有参数
void(xiaohong:: * xhSignal_y)(QString) = &xiaohong::eat;
void(xiaoming:: * xmSignal_y)(QString) = &xiaoming::buy;
connect(xh, xhSignal_y, xm, xmSignal_y);
connect(ui.pushButton_2, &QPushButton::clicked, this, &Afterwork::workoff_y);
}
Afterwork::~Afterwork()
{}
//触发信号
void Afterwork::workoff_n()
{
emit xh->eat();
ui.label->setText("She doesn't know what to eat.");
}
void Afterwork::workoff_y()
{
emit xh->eat("hamburger");
ui.label->setText("She wants a hamburger.");
}
七、运行效果
启动
点击,下班(没想法),无参
点击,下班(有想法),这里emit触发的时候传入的是hamburger,有参
八、总结
首先,xiaohong是负责发送信号的,有eat()和eat(QString food)两个发送信号方法,无参和有参
xiaoming是负责相应信号的,有buy()和buy(QString foodName)两个槽函数,用于相应xiaohong发过来的不同信号进行不同相应
无参绑定
void(xiaoming:: * xmSignal_n)(void) = &xiaoming::buy;
void(xiaohong:: * xhSignal_n)(void) = &xiaohong::eat;
connect(xh, xhSignal_n, xm, xmSignal_n);
connect(ui.pushButton, &QPushButton::clicked, this, &Afterwork::workoff_n);
将xiaohong的无参信号eat()和xiaoming的无参槽函数相应buy()进行绑定连接
将第一个button以及被点击信号和触发函数Afterwork::workoff_n()进行绑定用于触发xiaohong的eat()信号
因为之前connect(xh, xhSignal_n, xm, xmSignal_n);
已经将xiaohong和xiaoming进行了绑定,故xiaohong发出eat()信号,xiaoming进行槽函数buy()相应
有参绑定
void(xiaohong:: * xhSignal_y)(QString) = &xiaohong::eat;
void(xiaoming:: * xmSignal_y)(QString) = &xiaoming::buy;
connect(xh, xhSignal_y, xm, xmSignal_y);
connect(ui.pushButton_2, &QPushButton::clicked, this, &Afterwork::workoff_y);
将xiaohong的有参信号eat(QString food)和xiaoming的有参槽函数相应buy(QString foodName)进行绑定连接
将第二个button以及被点击信号和触发函数Afterwork::workoff_y进行绑定用于触发xiaohong的eat(QString food)信号
因为之前connect(xh, xhSignal_y, xm, xmSignal_y);
已经将xiaohong和xiaoming进行了绑定,故xiaohong发出eat(QString food)信号,xiaoming进行槽函数buy(QString foodName)相应
项目运行,启动Afterwork.ui页面,当用户点击不同的button从而进行不同的相应