day02C++QT框架学习
按钮的定义
//connnect (信号的发送者,发送信号、信号的接受者、处理的函数(槽函数))
//点击myBtn 关闭窗口
//参数1 信号发送者 参数2 发送的信号 参数3 信号的接收者 参数4 处理的槽函数(函数地址)
//高版本中去掉取地址符也可以运行,但是为了兼容性还是建议书写
//myBtn和btn是QPushButton的对象
//实现代码为:
MyButton * myBtn = new MyButton;
QPushButton * btn = new QPushButton;
//单单这么写是不会显示我们自定义的按钮的,因为没有调用他进行显示
可以调用show()方法或者在创建对象时这样书写:
QPushButton * myBtn = new QPushButton("按钮上的文字", this)
//使用connect函数可以让我们点击按钮时触发对应函
connect(myBtn, &MyButton::clicked, this, &Widget::close);
connect(btn,&QPushButton::clicked, this, &Widget::close);
//由于MyButton的作用域是在QPushButton中的,所以我们完全可以将发送信号的作用域用QPushButton的地址
//优点:松散耦合 将两个集合连接起来
下面使用connect实现需求
//有一个需求 刚刚创建的按钮没有作用 现在我想点击我的按钮 关闭窗口
//按钮->点击 窗口->关闭
//我们需要将这些功能连接起来
信号发出者->发送信号->信号的接收者->接收者调用自己的函数(槽函数)
创建两个类一个类是Student类 一个是学生类 老师类发出信号"hungry" 学生接收信号"treat"请客
student.h的定义:
#define STUDENT_H
#include <QObject>
class Student : public QObject
{
Q_OBJECT//添加这句可以使用信号和槽函数
public:
explicit Student(QObject *parent = nullptr);
signals://信号编写位置
public slots://槽函数编写位置
//自定义槽函数
//高版本可以写道 public下或者全局函数
//槽函数返回值为空
//槽函数需要声明也需要实现
//槽函数也可以有参数 可以发生重载
void treat();//有参的定义
void treat(QString foodName);//无参的定义
};
#endif // STUDENT_H
#ifndef TEACHER_H
#define TEACHER_H
Teacher.h文件的定义:
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
//自定义信号需要卸载signals中
signals://信号编写位置
//返回类型必须是void
//信号只需要声明 不需要实现
//信号可以传递参数,可以重载
void hungry();//有参的定义
void hungry(QString foodName);//无参的定义
};
#endif // TEACHER_H
主窗口定义Widget.h定义:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QPushButton>
#include<QDebug>
#include"teacher.h"
#include"student.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
Teacher * zt;
Student * st;
void classIsOver();
};
#endif // WIDGET_H
student.cpp定义
#include "student.h"
#include<QDebug>
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::treat()
{
qDebug() << "请老师吃饭";
}
void Student::treat(QString foodName)
{
// qDebug() << "请老师吃饭,老师要吃"<< foodName;
//去掉输出的时候带引号的问题 foodName带引号的问题
//QString 转char* toUtf8转QByteArray 在利用data 转成char*
qDebug() << "请老师吃饭,老师要吃" << foodName.toUtf8().data();
}
void Student::study(QString Objcet)
{
qDebug() << "学生要上课,上的科目是" << Objcet.toUtf8().data();
}/*添加类的时候忘记添加Q_OBJECT导致无法使用其槽函数等信号,我们需要在头文件中每个类的花括号下写入Q_OBJECT 然后修改.pro文件就可以了*/
由于Teacher类只是信号的发出者 信号只用声明不用实现这里Teacher.cpp中是QT框架原本定义
综上,Teacher类发出信号hungry -> 学生类接收信号后处理 -> 调用treat()
下面进行函数的实现:
//例如
/*#include <QObject>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
*/
//此时修改.pro文件添加空格或者删除空行使得qmake能够运行 就可以正常运行
#include "widget.h"
#include <QWidget>
#include<QPushButton>
#include<QDebug>
#include"teacher.h"
#include"student.h"
//需求:创建两个类 Teacher 类 Stdent 类
//下课后 老师Teacher zt 会发出一个信号 饿了
//zt 信号发送者 学生类响应信号
//处理信号的槽函数 请客吃饭
//学习自定信号
//老师类是信号的发出方 所以会在老师类中编写信号
//由于学生类是信号的接收方 所以会在学生类中书写槽函数
//信号是不用实现的只用声明 可以给予参数 槽函数必须声明必须实现
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
zt = new Teacher(this);//等于将老师类放到childen表中,之后就不用担心程序的释放
st = new Student(this);
//连接老师和学生
//connect(zt, &Teacher::hungry, st, &Student::treat);
//不触发按钮 就不会发生
//有参数的槽的连接
//函数指针 执行函数地址
//void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
//void(Student:: *stSlot)(QString) = &Student::treat;
//connect(zt, teacherSignal, st, stSlot);
//teacherSignal和StudentSlot本就是指针变量,指针里面存的是地址,所以这里不用取地址符
//函数调用
//classIsOver();
//点击下课 才下课
QPushButton * over_btn = new QPushButton("点击按钮下课",this);
//创建函数指针 由于这里我们定义了一个有参的情况一个无参的情况 程序指向不明 我们定义函数指针指向无参的函数使得 指向明确
void(Teacher:: *noTeacherSignal)(void) = &Teacher::hungry;
void(Student:: *noStSlot)(void) = &Student::treat;
//触发按钮
connect(over_btn, &QPushButton::clicked, zt, noTeacherSignal);//下课按钮
connect(zt,noTeacherSignal,st,noStSlot);
//connect(over_btn,&QPushButton::clicked,this,&Widget::close);//一个按钮可以触发多个槽函数
//重新设置窗口大小
resize(600,400);
//断开信号槽disconnect()
//disconnect(zt,noTeacherSignal,st,noStSlot);
//信号和槽的拓展
//1.信号可以连接信号
//2.信号和槽可以断开disconnect
//3.一个信号可以触发多个槽函数
//4.多个信号可以连接一个槽函数
//5.信号和槽的参数必须一一对应 信号的参数个数 可以多于槽函数的参数个数,但是必须类型一一对应
//槽函数的参数个数不能多于信号个数
//相当于需求可以有很多,但提供可以比需求少,反之,提供比需求多,会浪费资源
//QT4版本 信号和槽写法
connect(zt,SIGNAL(hungry(QString)), st, SLOT(treat(QString)));
classIsOver();
//不推荐QT4版本 当两个对应的类型不同时例如:
//优点:参数类型比较直观,发生重载也不用写函数指针
//缺点:参数类型不匹配时,编译器不会报错,但运行的时候就会报错
connect(zt,SIGNAL(hungry(QString)), st, SLOT(treat(void)));
connect(zt,SIGNAL(hungry(void)), st, SLOT(treat(QString)));
//不检测原因
//SIGNAL和SLOT下会把里面代码作为字符串处理
//Lambda表达式C++11支持Lambda 如果QT的版本过低的话需要在.pro文件中添加CONFUG += C++11
QPushButton * btn2 = new QPushButton("aaaa",this);
//[=](){}这是一个函数 添加()调用函数 这里的“=”是用来将作用范围内所有可见的局部变量 只有当有"="号的时候该函数才能找到变量
[=](){
btn2->setText("bbbb");
//btn-setText("cccc");这里由于[]中只有btn2这个时候btn无法在这个函数中被调用
}();
//mutable关键字 用于修改值传递的变量 进行修改
QPushButton * MyBtn = new QPushButton(this);
QPushButton * MyBtn2 = new QPushButton(this);
MyBtn2->move(100, 100);
int m = 10;
connect(MyBtn, &QPushButton::clicked, this, [m]()mutable{m = 100 + 10; qDebug() << m;});
connect(MyBtn2,&QPushButton::clicked, this, [=]{ qDebug() << m;});
qDebug() << m;
//返回值
int ret = []()->int{return 10000;}();
qDebug() << "ret = " << ret;
//用的最频繁的[=](){}
QPushButton * btn3 = new QPushButton("btn3", this);
btn3->move(200,0);
connect(btn3, &QPushButton::clicked,this, [=]()
{
btn3->setText("DDDDDDD");
});
//当我们的[]中使用&取地址符时
// connect(btn3, &QPushButton::clicked,this, [&]()
// {
// btn3->setText("DDDDDDD");
// });
//程序会崩掉
//做信号槽连接,默认内部变量会进行锁的状态,类似与只读状态,如果进行操作,程序会奔溃所以建议使用“="
//无参按钮调用 有参 请客吃饭
connect(btn3,&QPushButton::clicked, this, [=]()
{
zt->hungry("宫爆鸡丁");
});
//点击按钮程序关闭
connect(btn3, &QPushButton::clicked,this, [=]()
{
this->close();
}
);
}
void Widget::classIsOver()
{
//触发老师饿了的信号
//老师饿了的信号属于自定义信号,触发自定义信号关键字 emit
// emit zt->hungry();//触发无参信号
emit zt->hungry("宫保鸡丁");//触发有参的信号
}
本文来自博客园,作者:华岁渡春风,转载请注明原文链接:https://www.cnblogs.com/orsrrc/p/16193301.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本