Qt 学习笔记_01
Qt 学习笔记_01
1 Qt项目默认创建的文件
此处的main函数是Application项目的Widgets Application,基类选择的是QWidgets
(1)main.cpp
#include <QApplication>
#include <QWidget>
int main(int argc, char *argv[])
{
//应用程序对象,有且只有一个
QApplication a(argc, argv);
//实例化窗口对象
QWidget w;
/***
在B站教学视频演示中,新建了MyQWidget类,并让该类继承自QWidget,这样可以自定义QWidget的 构造函数,使得只要构造该对象就能自动创建一系列的控件
***/
//显示w窗口
w.show();
//让应用程序对象进入消息循环机制中,代母阻塞到当前行
return a.exec();
}
(2)项目文件
#-------------------------------------------------
#
# Project created by QtCreator 2022-02-22T13:48:52
#
#-------------------------------------------------
#Qt包含的模块
QT += core gui
#大于4以上的版本, 包含widgets模块(兼容)
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
#目标——生成exe文件的名称
TARGET = 01_Pro
#模板——应用程序模板
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
#源文件
SOURCES += \
main.cpp \
mywiget.cpp \
mypushbutton.cpp
#头文件
HEADERS += \
mywiget.h \
mypushbutton.h
2 按钮与窗口控件常用API
(1)按钮
Qt中的坐标系 左上角为(0, 0),x以右为正方向,y以下为正方向
-
创建 QPushButton * btn = new QPushButton
-
设置父亲 setParent(this) (设置父亲可以让该对象显示在父亲中,并且再释放时通过对象树依次释放,当然也可以直接在构造方法中传入父亲创建对象)
-
设置文本 setText(“文字”)
-
设置位置 move(宽,高)
(2)窗口
-
重新指定窗口大小 resize
-
设置窗口标题 setWindowTitle
-
设置窗口固定大小 setFixedSize
myWidget.cpp 中的构造函数(myWidget 是继承自QWidget的自定义类)
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
{
this->setWindowTitle("第一个图形窗口");
this->resize(400, 200);
//设置后不能调整窗口大小
//this->setFixedSize(400, 600);
QPushButton * btn1 = new QPushButton;
btn1->setParent(this);
btn1->setText("按钮1");
QPushButton * btn2 = new QPushButton;
btn2->setText("按钮2");
btn2->move(300, 0);
}
效果如下
3 信号和槽
先介绍一下可以把信号和槽关联起来的connect函数(四个参数都是地址)
connect(信号发送者, 发送的信号(函数地址), 信号的接受者, 处理的槽函数)
使用connect后,当特定事件发生时,发送者就会发送一个信号,接受者被连接的槽函数就会自动回调
(1)系统自带的信号和槽函数
//myWidget类的构造函数中
myPushButton * btn3 = new myPushButton(this);
btn3->setText("我自己的关闭按钮");
btn3->move(150, 75);
//这样连接后,当按下btn3按钮时,窗口就会关闭
connect(btn3, &QPushButton::clicked, this, &QWidget::close);
(2)自定义信号和槽
① 自定义信号
-
写到 头文件的signals下
-
返回值为void
-
只需要声明,不需要实现
-
可以有参数 ,可以重载
② 自定义槽函数
-
写到 public slot下 或者public 或者全局函数
-
返回值为 void
-
既需要声明 ,也需要实现
-
可以有参数 ,可以重载
-
emit 自定义信号 进行触发
案例:下课会触发 老师“饿了”信号, 学生响应信号,请客吃饭
//1. teacher.h中的signal(自定义信号只需要声明,不需要实现)
signals:
void hungry();
void hungry(QString food);
//2. student.h中的public slots
public slots:
void treat();
void treat(QString food);
//3. student.cpp中槽函数的实现
void Student::treat()
{
qDebug() << "请老师吃饭!";
}
void Student::treat(QString food)
{
//用qDebug打印调试信息时,QString类的内容会自动用" "括起来
//qDebug() << "请老师吃饭, 老师要吃" << food;
//去掉" "方法:先用toUtf8()转成QByteArray,再用data()转成char *
qDebug() << "请老师吃饭, 老师要吃" << food.toUtf8().data();
}
//4. 定义一个下课函数,用来递交 老师"饿了"的信号
void Widget::classIsOver()
{
emit tc->hungry("宫保鸡丁");
}
//5.1 (Widget.cpp的构造函数)如果没有重载的信号和槽,则可以用如下写法:
/*
//此处的tc和st分别为teacher.h和student.h类的指针,在Widget.h类中私有创建
this->tc = new Teacher(this);
this->st = new Student(this);
QPushButton * btn = new QPushButton(this);
btn->setText("下课");
connect(btn, &QPushButton::clicked, tc, &Teacher::hungry);
connect(tc, &Teacher::hungry, st, &Student::treat);
*/
//5.2 (Widget.cpp的构造函数) 有重载的信号或槽,需要用函数指针来指向特定参数的信号
this->tc = new Teacher(this);
this->st = new Student(this);
//函数指针来指向 重载的有参函数地址
void (Teacher:: *teacherSignal) (QString) = &Teacher::hungry;
void (Student:: *studentSlot) (QString) = &Student::treat;
connect(tc, teacherSignal, st, studentSlot);
QPushButton * btn2 = new QPushButton(this);
btn2->setText("下课(有参版)");
connect(btn2, &QPushButton::clicked, this, &Widget::classIsOver);
//classIsOver函数实现
void Widget::classIsOver()
{
//传参在这儿传的
emit tc->hungry("鱼香肉丝");
}
(3)拓展
- 信号可以连接信号
//点击按钮,老师发送"饿了"信号
connect(btn, &QPushButton::clicked, tc, &Teacher::hungry);
-
一个信号可以连接多个槽函数
-
多个信号可以连接同一个槽函数
-
信号和槽函数的参数 必须类型一一对应
-
信号的参数个数 可以多于槽函数的参数个数
-
信号槽可以断开连接 disconnect
//断开连接
disconnect(tc,teacherSignal,st,studentSlot);
- Qt4版本写法
//利用Qt4信号槽 连接无参版本
connect(zt,SIGNAL(hungry()) , st , SLOT(treat()));
/*
Qt4版本 底层SIGNAL("hungry") SLOT( "treat") 进行字符串比较
Qt4版本优点:参数直观,缺点 :类型不做检测
Qt5以上 支持 Qt4的版本写法
*/
(4) Lambda表达式
用Lambda表达式作为槽函数,能更简便的实现一些比较简单的槽函数
组成:
[capture](parameters) mutable ->return-type{
statement
}
- [] Capture 子句——内容为要访问Lambda表达式作用范围内所有可见的局部变量,为空则不访问, = 为值传递访问, & 为引用传递访问,也可以添加单个变量来单独访问该变量
//1. m按引用传递,其余按值传递
[=,&m](){
//...
}
//2. a按值传递, 其余按引用传递
[&, a](){
//...
}
//3. 函数体内可以使用lambda所在类中的所有成员变量
[this](){
//...
}
//4. a值传递, b引用传递
[a, *b](){
//...
}
- ( ) 参数列表(可省略)
- { } 实现体
//使用Lambda表达式来替代 classIsOver
connect(btn2, &QPushButton::clicked, this, [=](){
emit tc->hungry("好吃的东西");
});
- mutable 可修改标识符,添加后可以修改值传递的参数,但修改的只是备份,不能影响Lambda表达式外的变量值
//Lambda表达式外的m不会因为Lambda的操作而改变值
[m](){
m = 1 + 2;
qDebug() << m;
}
- 返回值 -> 标识返回值类型,若返回值类型为 void 或 函数体内只有一条return,则可省略
int ret = []()->int{
return 1000;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】