该笔记的内容摘自于传智播客B站视频:https://www.bilibili.com/video/BV1g4411H78N?p=17,只用作自己的学习与分享,侵删。
另外,视频质量很好,推荐一波~
1.1 什么是Qt
Qt是一个跨平台的C++图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。
1.2 Qt的优点
1.3 成功案例
2.1 创建选项
常用默认选项Application:创建一个桌面Qt应用,包含一个基于Qt设计师的主窗体。预选一个可用的Qt桌面版本用于编译程序。
注意:创建的文件名称不能有中文可以有下划线,路径不能出现中文。
三大基类:QWidget是QMainWindow和QDialog的父类(继承),QWdiget是空的,QMainWindow多了状态栏,QDialog和对话框有关。
创建界面(Generate form)如果选✔会多出来ui文件,可直接拖拽框架使用。
2.2 main.cpp
#include "mywidget.h"
#include // 包含一个应用程序类的头文件
//main程序入口 argc命令行变量的数量 argv命令行变量的数组
int main(int argc, char *argv[])
{
//a应用程序对象,在Qt中,应用程序对象 有且仅有一个
QApplication a(argc, argv);
//窗口对象 myWidget父类 -> QWidget
myWidget w;
//窗口对象 默认不会显示,必须要调用show方法显示窗口
w.show();
//让应用程序对象进入消息循环
//当代码阻塞到这行
return a.exec();
//保证窗口的持续存在,防止一闪而过,直到点击右上角的叉关闭
}
2.3 widget.h
#ifndef WIDGET_H//#ifndef是"if not defined"的简写
#define WIDGET_H//防止头文件重复包含
#include //包含头文件 QWidget 窗口类
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT // Q_OBJECT宏,允许类中使用信号和槽的机制
public:
Widget(QWidget *parent = nullptr); //构造函数
~Widget(); //析构函数
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
2.4 命名规范
2.5 快捷键
2.6 帮助文档用法
按F1快捷键可找到帮助文档,或者去安装目录里找bin文件,其中也有帮助文档。
主要用于了解类的基本信息:
下移,找类的使用方法,点进去即可看到详情
2.6 创建第一个PushButoon
widget.cpp文件
#include "widget.h"
#include
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//创建一个按钮
QPushButton * btn = new QPushButton;
//在帮助文档中可找到父类为QWidget,窗口默认不显示,需要用show方法
//btn->show(); 直接使用,会出现单独的窗口,而不是出现在主窗口之内
//需求:让btn对象 依赖在 widget窗口中
btn->setParent(this);
//显示文本
btn->setText("第一个按钮");
//创建第二个按钮 按照控件的大小创建窗口
QPushButton * btn2 = new QPushButton;
btn2->setParent(this);
btn2->setText("第二个按钮");
//移动btn2的位置
btn2->move(150,20);//x,y坐标
//改变btn2的大小
btn2->resize(100,70);
//重置窗口大小
resize(220,110);//resize(int w,int h):宽,高
//设置固定的窗口的大小,使得用户无法用鼠标拖拽窗口大小
setFixedSize(600,400);
//设置窗口标题
setWindowTitle("第一个窗口");
}
Widget::~Widget()
{
}
注意:文字不能正常显示的情况,菜单栏找到工具->选项->文本编辑器->行为-> 默认编码,设置为UTF-8即可。
总的来说:一个parent被析构时,会自动delete/析构它所有的children;一个children被析构时,会自动从他的parent中移除。
5.1 样例
信号的英文单词为signal,槽的单词为slot,可以去帮助文档中找相关信息,如果找不到可以去父类中查找。
这里是PushButoon的相关信号:
用connect函数连接信号和槽
widget.cpp代码如下:
#include "widget.h"
#include
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QPushButton * myBtn = new QPushButton;
myBtn->setText("关闭按钮");
myBtn->setParent(this);
//需求 点关闭按钮 关闭窗口
//参数1 信号的发生者 参数2 发送的信号(函数的地址) 参数3 信号的接收者 参数4 处理的槽函数
connect(myBtn,&QPushButton::clicked,this,&Widget::close);
}
Widget::~Widget()
{
}
点击按钮即可关闭窗口
5.2 自定义的信号和槽
建立一个老师类和学生类,自定义信号和槽
首先右键项目 -> Add New… -> 选C++ Class类 -> Base Class 选择 QObject 确认
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
public slots:
//槽函数,早期Qt必须写在public slots下面,高级版本可以写到public或全局下
//返回值 void , 需要声明, 也需要实现, 可以有参数, 可以发生重载
void Hello();
};
#endif // STUDENT_H
teacher.h
#ifndef TEACHER_H
#define TEACHER_H
#include
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
//自定义信号写到signals下面
//规定:返回值是void,只需要声明,不需要实现
//可以有参数,可以重载
void StandUp();
};
#endif // TEACHER_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Teacher *ls;
Student *xs;
void ClassStart();
};
#endif // WIDGET_H
student.cpp
#include "student.h"
#include
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::Hello()
{
//调试信息直接输出到控制台上
qDebug()<<"老师好!";
}
widget.cpp
#include "widget.h"
#include
//Teacher 类 老师类
//Student 类 学生类
//上课铃响 老师会触发一个信号,说起立,学生响应信号,回应老师好
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//创建一个老师d对象
this->ls = new Teacher(this);
//创建一个学生对象
this->xs = new Student(this);
//上课铃响,老师喊起立,学生回应老师好
connect(ls,&Teacher::StandUp,xs,&Student::Hello);
ClassStart();//注意代码顺序,先连接,再触发才有效
}
void Widget::ClassStart()
{
//上课,调用后, 老师触发信号
emit ls->StandUp();
}
Widget::~Widget()
{
}
5.3 信号和槽重载的解决 更新widget.cpp文件如下: 效果如下: 5.4.1 代码样例 运行后点击按钮即可触发对应函数可直接触发老师类的StandUp,再触发学生类的Hello。 5.4.2 拓展 6.1 介绍 [函数对象参数](操作符重载函数参数)mutable->返回值(函数体) ① 函数对象参数 ③ 可修改标识符 ④ 函数返回值 ⑤ 函数体 6.2 试用样例 先输出1000,然后每次点击按钮会输出110和10。 lambda表达 最常用:[=](){} 要求实现:一个按钮开始显示“Open",点击Open打开窗口并且显示改为"Close",点击Close又会关闭打开的窗口,并且文本变回"Open”。 代码如下:
在上述程序的基础上,Teacher类的头文件中加上声明 void StandUp(QString sentence); Stuendent类的头文件中加上声明 void Hello(QString sentence),并在cpp文件中写好函数体 qDebug()<<“老师”<#include "widget.h"
#include
可以看到上述输出sentence的文字,本没有加引号,但是输出了引号。将对应输出改成如下格式即可消去引号。
5.4 信号连接信号#include "widget.h"
#include
6 Lambda表达式
C++11 中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。
-基本构成:[capture](parameters)mutable->return-type
{
statement
}
[],标识一个lambda的开始,这部分不可省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义lambda为止时lambda所在作用范围内可见的局部变量(包括lambda所在类的this)。函数对象参数有以下形式:
② 操作符重载函数参数
标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。
mutable声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。
->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。
{},标号函数的实现,这部分不能省略,但函数体可以为空。#include "widget.h"
#include
注意:在上述代码中按钮连接的lambda表达式中不能用k值,因为不在作用域内;如果lambda第三个参数是this可以省略该参数。7 小作业
#include "widget.h"
#include