Qt自定义信号和槽
2023-03-14 22:49:34 时间
案例需求: 创建一个老师类和学生类,下课后,老师触发饿了的信号,学生响应老师饿了的信号,并且请老师吃饭 老师类 .h
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
//自定义信号,写到signal下
signals:
//返回值是void
//只需要声明,不需要实现
//可以有参数,可以发生重载
void hungry();
};
#endif // TEACHER_H
.cpp
#include "teacher.h"
Teacher::Teacher(QObject *parent) : QObject(parent)
{
}
学生类 .cpp
#include "student.h"
#include<QDebug>
Student::Student(QObject *parent) : QObject(parent)
{
}
//学生的槽函数
void Student::treat()
{
qDebug()<<"请老师吃饭"<<endl;
}
.h
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
//返回值是void
//需要有声明,需要有实现
//可以有参数,可以发生重载
void treat();
signals:
};
#endif // STUDENT_H
这里注意槽函数的版本区别:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include"student.h"
#include"teacher.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
Student* st;
Teacher* tt;
void classisover();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
st=new Student(this);
tt=new Teacher(this);
//连接信号和槽
connect(tt,&Teacher::hungry,st,&Student::treat);
//调用该函数,这样信号和槽连接后,调用该函数后才能触发信号
classisover();
}
void Widget::classisover()
{
//触发老师饿了的信号
emit tt->hungry();
}
Widget::~Widget()
{
}
上面为什么连接信号和槽后,还要再写一个classisover函数来触发信号呢? 因为连接信号和槽是为了确保在信号被触发的时候,槽函数能够执行来处理事件,而这里我们这是连接了老师的信号和学生的槽函数,还需要触发老师饿了的信号,即调用老师的hungry函数
自定义信号和槽重载发生的问题及解决措施
上面两张图片可知,我们重载了有参的信号和槽,此时我们再连接信号和槽:因为有参信号和槽连接和无参信号和槽连接写法一致,系统无法区分,就会报错
解决方法:利用函数指针指向函数地址 widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
st=new Student(this);
tt=new Teacher(this);
//连接信号和槽
//connect(tt,&Teacher::hungry,st,&Student::treat);
//连接有参的信号和槽
//函数指针可以指向函数地址
//这里槽函数和信号函数取地址都要加&
//因为这里是在当前Widget的构造函数里面调用Teacher类和Student类里面的函数,所以要加类名作用域
void(Teacher::*ttSignal)(QString)=&Teacher::hungry;
void(Student::*stSlot)(QString)=&Student::treat;
//将原来的函数地址替换成函数指针
connect(tt,ttSignal,st,stSlot);
//调用该函数,这样信号和槽连接后,调用该函数后才能触发信号
classisover();
}
void Widget::classisover()
{
//触发老师饿了的信号
//emit tt->hungry();
//触发老师饿了的有参信号
emit tt->hungry("火锅,烧烤,麻辣烫!!!");
}
Widget::~Widget()
{
}
解决输出字符串加上双引号的问题?
//学生槽函数的重载版本
void Student::treat(QString foodName)
{
//QString 转char*就可以解决双引号问题
//转char*方法:
//先通过.toUtf8变为QByteArray类型,再通过.data()变为char*
qDebug()<<"请老师吃"<<foodName.toUtf8().data()<<endl;
}
总结:当信号和槽发生重载的时候,需要通过函数指针明确指出函数地址
信号连接信号
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
st=new Student(this);
tt=new Teacher(this);
//创建自己的按钮控件
QPushButton* mybtn=new QPushButton("下课",this);
resize(600,400);
void(Teacher::*ttSignal)()=&Teacher::hungry;
void(Student::*stSlot)()=&Student::treat;
//信号和槽连接
connect(tt,ttSignal,st,stSlot);
//信号是可以连接信号的
connect(mybtn,&QPushButton::clicked,tt,ttSignal);
//当老师饿了的信号由按钮点击来触发以后,就不需要专门的函数来调用老师饿了的函数,来触发饿了信号,因此下面这个下课函数可以不写
//classisover();
}
void Widget::classisover()
{
emit tt->hungry("火锅,烧烤,麻辣烫!!!");
}
Widget::~Widget()
{
}
可以断开信号和槽的连接
st=new Student(this);
tt=new Teacher(this);
//创建自己的按钮控件
QPushButton* mybtn=new QPushButton("下课",this);
resize(600,400);
void(Teacher::*ttSignal)()=&Teacher::hungry;
void(Student::*stSlot)()=&Student::treat;
//信号和槽连接
connect(tt,ttSignal,st,stSlot);
//信号是可以连接信号的
connect(mybtn,&QPushButton::clicked,tt,ttSignal);
//断开信号和槽的连接
disconnect(tt,ttSignal,st,stSlot);
一个信号可以响应多个槽函数
可以通过多写几个connect函数,将同一个信号和多个槽函数相连接
多个信号可以连接同一个槽函数
可以通过多写几个connect函数,将同一个槽函数和多个信号相连接
信号和槽函数的参数个数和参数类型必须一一对应
信号的参数个数可以多余槽函数参数个数,反之不可以
Qt4版本的信号和槽的写法
信号和槽总结
相关文章
- Linux系统中‘dmesg’命令处理故障和收集系统信息的7种用法
- Classify Text With NLTK
- DevOps:软件架构师行动指南2.1 概述
- 一个purge参数引发的惨案——从线上hbase数据被删事故说起
- 用机器算法预测自杀倾向
- DevOps:软件架构师行动指南2.2 云的特性
- 快速排序及优化
- DevOps:软件架构师行动指南DevOps:软件架构师行动指南2.3 独特的云特性对DevOps的影响
- Linux有问必答:如何检查我是否处于一个运行着的screen会话中
- Hadoop- The Definitive Guide 笔记二
- DevOps:软件架构师行动指南2.4 小结
- DevOps:软件架构师行动指南2.5 更多阅读材料
- LinkedList的局限
- 堆排序-算法导论
- Linux 内核的测试和调试(1)
- DevOps:软件架构师行动指南3.1 概述
- java.util.HashMap源码要点浅析
- DevOps:软件架构师行动指南3.2 运维服务
- xmemcached发布1.10 RC1 (附最新测试报告,update)
- Linux有问必答:如何查看Linux上程序或进程用到的库