(一)解决方案
1.方案
在 student.h 中
#ifndef STUDENT_H #define STUDENT_H #include <QObject> class Student : public QObject { Q_OBJECT public: explicit Student(QObject *parent = nullptr); signals: public slots: //早期的Qt版本 自定义槽函数必须写到public slots下 //高级的Qt版本 自定义槽函数可以写到public slots、public下或全局作用域下 //返回值 void ,需要声明,也需要实现 //可以有参数,也可以发生重载 void run(); void run(QString type); }; #endif // STUDENT_H
在 teacher.h 中
#ifndef TEACHER_H #define TEACHER_H #include <QObject> class Teacher : public QObject { Q_OBJECT public: explicit Teacher(QObject *parent = nullptr); signals: //自定义信号 写到signals下 //返回值是void,只需要声明,不需要实现 //可以有参数,可以重载 void classoff(); void classoff(QString type); }; #endif // TEACHER_H
在 student.cpp 中
#include "student.h" #include <QDebug> Student::Student(QObject *parent) : QObject(parent) { } void Student ::run() { qDebug()<<"抢饭第一名"; } void Student ::run(QString type) { qDebug()<<"抢饭第一名"<<type; }
在 teacher.cpp 中,因为信号只需声明,而不用实现。
#include "teacher.h" Teacher::Teacher(QObject *parent) : QObject(parent) { }
在 mywidget.cpp 中
myWidget::myWidget(QWidget *parent) : QWidget(parent)//这个在C++语法中被称为初始化列表 { //创建一个老师的对象 this ->wu =new Teacher(this); //创建一个学生的对象 this ->ming =new Student(this); //下课铃响了(相当于是按键的点击事件),老师(信号的发送者)说下课(信号),小明(信号的接收者)往外跑(槽函数)。 //指针可以指向地址,现在要指向&Teacher::classoff(是一个函数的地址) //因此要定义一个函数指针 //我们在声明一个成员函数的函数地址时,要把成员函数的作用域也放到指针的前面 void (Teacher:: *teacherSignal)(QString)=&Teacher::classoff; //同理,槽函数也要进行修改 void (Student:: *studentSlot)(QString)=&Student::run; //要先做好连接 connect(wu,teacherSignal,ming,studentSlot); ring(); } //下课铃响函数,该函数运行后,将触发老师说下课(信号),小明向外跑(槽函数) void myWidget:: ring() { //释放老师说下课(信号) //emit wu->classoff(); emit wu->classoff("放假"); }
当程序运行后,
输出: 抢饭第一名"放假"
2.注意
1、要先建立连接,再有发生事件。
2、当发生事件后,发送者发送信号,接收者接收到信号后,执行槽函数。
3、需要注意的是槽函数需要与信号一致(参数,返回值)。也就是说如果信号没有返回值,那么槽函数一定没有返回值。如果槽函数有参数,那么信号一定也有参数。因为槽函数中的参数是用来接收信号所带的参数的。
还要注意这里的发生事件( ring函数 )打印出来的是有双引号的。
这是因为自定义信号中的参数是 QString 类型的
void classoff(QString type);
void myWidget:: ring() { emit wu->classoff("放假"); }
相应的槽函数要遵循与信号一致(参数,返回值)的原则,所以参数也要定义为 QString 类型,正是因为 QString 类型的原因,所以才会有引号。
void run(QString type);
void Student ::run(QString type) { qDebug()<<"抢饭第一名"<<type; }
3.去除引号
要进行格式转换。转换成 char * 类型就不加引号了。
那怎么转换呢?首先,要明确它不是直接就可以转换的。
而是要先转换成 QByteArray (利用 toUtf8 这个方法)之后,再转化成 char * 类型的。
void Student ::run(QString type) { qDebug()<<"抢饭第一名"<<type.toUtf8().data(); }
输出: 抢饭第一名 放假
(二)例子
//character.h // 需要发送HintLabel void submitHint(QString)const;
//gamescene.h void receiveHint(const QString str,const bool next)const;// 给出提示框 void receiveHint(QString str);// 给出提示框
//gamescene.cpp void (GameScene:: * studentSlot)(QString) = &GameScene::receiveHint; connect(m_character[i], &Character::submitHint, this, studentSlot);
(三)信号与槽不能有缺省参数。
既然signal->slot绑定是发生在运行时刻,那么,从概念上讲使用缺省参数是困难的。下面的用法是不合理的:
class SomeClass : public QObject { Q_OBJECT public slots: void someSlot(int x=100); // 将x的缺省值定义成100,在槽函数声明中使用是错误的 };
是就目前来说是不正确的。
标签:函数,自定义,void,QString,信号,Student,重载,public From: https://www.cnblogs.com/imreW/p/17142620.html