1. Qt概述
-
Qt 是一个跨平台的 C++图形用户界面应用程序的开发框架。
-
图形用户界面: GUI (Graphical User Interface)
-
框架:别人写好的一堆类(工具包)和开发规则。使用框架开发,能够大大降低程序的开发难度,提升开发效率,节约开发成本。
-
跨平台: 一次编写,在不同平台上无需改动(或少量改动)就可以形成在不同平台上运行的版本,例如:Windows、Linux、Mac等
-
-
Qt 还支持嵌入式和移动开发,例如:IOS、Android、Embedded linux和WinRT等。
-
桌面程序 和 C/S结构的程序
Qt 发展史:
-
Qt 的前身为创始于1994年的 Trolltech(奇趣科技)
-
Trolltech 于2008年6月被 Nokia(诺基亚)收购
-
2011年3月 Qt 被芬兰的 Digia 公司收购
Qt版本介绍:
-
Qt目前有 Qt4、Qt5、Qt6三个版本
-
Qt4.8.7 是 Qt4 的最终版本,也是 Qt4 系列中最稳定的版本,很多老项目还是会用 Qt4 进行维护
-
Qt5 是现在最常用的版本
-
Qt5.6.3 是最后支持xp系统的长期支持版本;
-
Qt5.12.3 是最后提供mysql数据库插件的版本,往后的版本需要自行编译对应的 mysql 数据库插件;
-
Qt5.12.5 是最后样式表性能最高的版本; QSS
-
Qt5.14.2 是最后提供离线安装包的版本,后面的版本都要在线安装;
-
Qt5.15 系列是最后支持 win7 的版本
-
-
Qt6 是最新版本,还在不断更新,解决BUG,目前不是很稳定。
2. 安装Qt
-
Qt 开发有专门的编辑器 -- Qt Creator
-
下载地址:
-
不同操作系统需要下载不同软件去安装
-
注意事项: 安装路径中不允许有中文、空格或特殊符号
安装步骤:
- 双击安装程序
- 注册账号
链接地址:Qt Account Loginhttps://login.qt.io/register
- 输入Qt的账号密码(也可以跳过 勾选
I accept ...)
- 设置安装目录
5.选择组件
6.接受协议 7.安装
3. 创建项目
- 点击 "+ New Project" 创建新项目
2.选择模版
3.设置项目创建路径
4.选择编译器
5.类名设置
-
首字母大写
-
不要勾选 创建界面
-
QWidget: 空窗口
-
QMainWindow: 主窗口
-
QDialog: 对话框
6.配置版本管理软件
7.测试
4. 项目文件解析
基础项目包含了4个文件:
-
工程文件: 01_first_project.pro
-
头文件: MyWidget.h
-
源文件: main.cpp MyWidget.cpp
-
用户配置文件: 01_first_project.pro.user
工程文件: qmake自动生成的用于产生 makefile 的配置文件
cpp
# 项目需要包含的模块
Qt += core gui
# 当Qt版本大于4时,包含的模块
greaterThan(Qt_MAJOR_VERSION, 4): Qt += widgets
# 产生的可执行程序(.exe) 的文件名
TARGET = 01_first_project
# 程序的生成模式。 app代表生成 .exe 可执行程序, lib 代表生成 .dll 动态链接库
TEMPLATE = app
# 编译选项,当项目中出现某些被标记为过时模块时,会报警
DEFINES += Qt_DEPRECATED_WARNINGS
CONFIG += c++11
# 项目中包含的源文件
SOURCES += \
main.cpp \
Widget.cpp
# 项目中包含的头文件
HEADERS += \
Widget.h
# 项目部署的默认规则
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
main.cpp: 项目入口文件
cpp
#include "Widget.h"
// 包含应用程序类型的头文件
#include <QApplication>
// 入口函数
int main(int argc, char *argv[])
{
// 实例化应用程序对象,该对象有且仅有一个
QApplication a(argc, argv);
// 实例化窗口对象, widget 代表空窗口
Widget w;
// 调用 show 方法显示创建好的空窗口
w.show();
// 让应用程序对象进入消息循环。 没有该方法,程序启动后马上会被销毁
return a.exec();
}
MyWidget.h: 窗口类头文件
-
Widget 是系统提供的空窗口基类
-
该头文件中,对空创建基类进行了二次封装,如果需要在创建窗口时实现额外的功能,可以在该文件中实现
cpp
#ifndef MYWIDGET_H
#define MYWIDGET_H
// 包含系统提供的 QWidget 类
#include <QWidget>
class Widget : public QWidget
{
// Q_OBJECT宏,设置了该宏之后,就能在项目中使用 信号 和 槽
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
};
#endif // MYWIDGET_H
MyWidget.cpp
cpp
#include "MyWidget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
}
Widget::~Widget()
{
}
5. Widget 空窗口
-
Widget 类的作用是创建一个空窗口
-
该类中提供了很多方法,能够实现窗口的外观设置
cpp
#include "MyWidget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
// 设置窗口标题
this->setWindowTitle("我的第一个App");
// 设置窗口大小
this->resize(500, 300);
// 设置窗口固定大小(不能拖拽修改)
this->setFixedSize(500, 300);
}
6. 常用基础部件
Qt中提供了非常多的部件,使用这些部件能够开发出图形化的用户界面
6.1 QLabel
QLabel 能够在窗口中设置文本
常用方法:
-
setText: 设置 QLabel 中要显示的文本
-
setParent: 设置父部件(显示在哪个部件中)
-
move: 设置在窗口中显示的位置
-
resize: 设置QLabel 所占的区域
-
setFont: 设置文本的字体
cpp
#include <QLabel>
#include <QFont>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->setWindowTitle("Hello");
this->resize(500, 300);
// 创建 QLabel 对象
QLabel *l1 = new QLabel;
// 设置文本内容
l1->setText("Hello,你好啊!!!");
// 设置文本显示位置
l1->move(100, 100);
// 设置文本区域大小
l1->resize(200, 100);
// 设置文本对齐方式, 默认水平左对齐 垂直中对齐
l1->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
// 设置文本使用字体
l1->setFont(QFont("楷体"));
// 将文本框加入到父级,也就是 Widget 空窗口中
l1->setParent(this);
}
6.2 QFont
QFont 专门用来设置字体
常用方法:
-
setBold(true); 是否加粗
-
setFamily("楷体"); 设置字形
-
setItalic(true); 设置倾斜
-
setPointSize(20); 设置字体大小
-
setWeight(QFont::Black); 设置加粗
cpp
#include <QFont>
// 参数1: 显示文本
// 参数2: 当前窗口对象,将创建好的 QLabel 直接挂载到当前窗口中
QLabel *l2 = new QLabel("QFont字体测试", this);
// 设置字体
QFont font;
font.setBold(true);
font.setFamily("楷体");
font.setItalic(true);
font.setPointSize(20);
font.setWeight(QFont::Black);
// 设置 l 应用字体
l2->setFont(font);
6.3 QPushButton
方式一:
cpp
#include <QPushButton>
QPushButton *btn1 = new QPushButton;
btn1->setText("按钮1");
btn1->resize(80, 30);
btn1->move(50, 0);
btn1->setParent(this);
方式二:
cpp
// 参数1: 按钮中的文本
// 参数2: 父组件设置
QPushButton *btn2 = new QPushButton("按钮2", this);
btn2->move(200, 0);
btn2->setFont(QFont("楷体"));
6.4 QLineEdit
cpp
#include <QLineEdit>
// 单行文本框
QLineEdit *txt = new QLineEdit;
txt->resize(100, 40);
txt->setText("请输入内容");
txt->resize(100, 30);
txt->move(200, 30);
txt->setParent(this);
6.5 登录界面
cpp
// 窗口设置
this->setWindowTitle("游戏登录");
this->setFixedSize(500, 300);
// 请登录标题
QLabel *loginLabel = new QLabel("请登录", this);
loginLabel->setFont(QFont("黑体", 30, QFont::Black));
loginLabel->resize(150, 50);
loginLabel->move(177, 20);
// 提供给账号和密码标签使用
QFont f("黑体", 14);
// 账号设置
QLabel *accountLabel = new QLabel("账号:", this);
accountLabel->move(85, 98);
accountLabel->setFont(f);
QLineEdit *accoutEdit = new QLineEdit(this);
accoutEdit->move(140, 95);
accoutEdit->resize(250, 40);
accoutEdit->setPlaceholderText("账号名/手机号/邮箱");
// 密码设置
QLabel *pwdLabel = new QLabel("密码:", this);
pwdLabel->move(85, 160);
pwdLabel->setFont(f);
QLineEdit *pwdEdit = new QLineEdit(this);
pwdEdit->move(140, 155);
pwdEdit->resize(250, 40);
pwdEdit->setPlaceholderText("密码");
// setEchoMode 用来设置QLineEdit 中的文本状态
// QLineEdit::Normal: 正常状态,明文显示
// QLineEdit::Password: 密码状态, 密文显示
// QLineEdit::PasswordEchoOnEdit: 输入时明文,失焦时密文
pwdEdit->setEchoMode(QLineEdit::Password);
// 切换按钮
QPushButton *chgBtn = new QPushButton("明文", this);
chgBtn->resize(60, 40);
chgBtn->move(330, 155);
// 重置和登录按钮
QPushButton *resetBtn = new QPushButton("重置", this);
QPushButton *loginBtn = new QPushButton("登录", this);
resetBtn->resize(80, 40);
loginBtn->resize(80, 40);
resetBtn->move(135, 220);
loginBtn->move(285, 220);
setEchoMode : 设置输出模式
-
QLineEdit::Password: 密码形式(密文输出)
-
QLineEdit::PasswordEchoOnEdit : 输入时明文,失焦后变为密文
7. 信号和槽
7.1 概述
-
信号 和 槽 用于两个对象之间的通信,是 Qt 特有的消息传输机制。
-
作用: 对一个部件进行操作时,另一个部件可以进行响应。
-
信号函数 和 槽函数 通常位于某个类中
-
信号函数用 signals 关键字修饰,
-
槽函数用 public slots、protected slots 、private slots 修饰
-
signals 和 slots 是 Qt 在 C++ 的基础上扩展的关键字,专门用来指明信号函数和槽函数
-
-
connect 用于链接 信号 和 槽,使其产生需要的效果
cpp
// 参数1: 发送信号的部件
// 参数2: 发送的信号类型 (函数地址)
// 参数3: 处理信号的部件
// 参数4: 处理信号的方法 (函数地址)
connect(参数1, 参数2, 参数3, 参数4);
// 参数1: 一个按钮对象 QPushButton
// 参数2: 发出点击信号
// 参数3: 窗口对象 QWidget
// 参数4: 执行的关闭函数
connect(myBtn, &QPushButton::clicked, this, &QWidget::close);
当 myBtn 按钮,发出一个点击信号时,当前的窗口对象 QWidget 就会关闭
7.2 快速上手
-
QPushButton 的信号:QPushButton 没有信号,但是 QPushButton 继承于 QAbstractButton, QAbstractButton 提供了若干信号
-
clicked() : 点击信号
-
pressed() : 按钮被按下的信号
-
released() : 按钮释放的信号
-
QWidget 的槽 (内置槽函数,功能固定)
示例:
- 点击最小化按钮时,将窗口隐藏到任务栏
核心: 按钮发送信号, 窗口响应信号并进行处理
-
点击最大化按钮时,将窗口最大化显示
-
点击关闭按钮时,关闭窗口
-
点击恢复按钮,窗口大小恢复到初始状态
cpp
// 最小化功能
QPushButton *minBtn = new QPushButton("最小化", this);
minBtn->move(10, 0);
// 参数1: 最小化按钮
// 参数2: 点击信号
// 参数3: 当前窗口对象
// 参数4: 内置的最小化槽函数
connect(minBtn, &QPushButton::clicked, this, &QWidget::showMinimized);
// 最大化功能
QPushButton *maxBtn = new QPushButton("最大化", this);
maxBtn->move(100, 0);
// &QPushButton::pressed 按下信号,按下即触发
connect(maxBtn, &QPushButton::pressed, this, &QWidget::showMaximized);
// 恢复功能
QPushButton *resetBtn = new QPushButton("恢复", this);
resetBtn->move(200, 0);
connect(resetBtn, &QPushButton::clicked, this, &QWidget::showNormal);
// 关闭窗口
QPushButton *closeBtn = new QPushButton("关闭", this);
closeBtn->move(300, 0);
connect(closeBtn, &QPushButton::pressed, this, &QWidget::close);
7.3 槽函数设置
槽函数设置在 public/protected/private slots 或者 public 中
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
//在public/private/protected slots 节点现爱可以设置自定义槽函数
public:
void response();
};
#endif // WIDGET_H
//.c
#include "widget.h"
#include <QPushButton>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//自定义槽函数
QPushButton *btn1 = new QPushButton("click",this);
btn1->move(20,60);
connect(btn1,&QPushButton::clicked,this,&Widget::response);
}
void Widget::response()
{
qDebug() << "大头娃娃真难打....";
}
7.4 Lambda 槽函数
cpp
// 参数3: lambda格式的处理信号的方法
connect(参数1, 参数2, lambda函数);
使用lambda 表达式/
QPushButton *btn2 = new QPushButton("lambda",this);
btn2->move(120,60);
//使用lambda表达式可以省略参数3
//当信号发送时,就会自动执行lambda函数
connect(btn2,&QPushButton::released,[](){
qDebug() <<"黄风岭,八百里,全是大耗子...";
});
7.5 登录完善
目标:
-
点击重置按钮时,将表单内容重置为初始内容
-
当用户输入 admin 和 123123 时,提示 "登录成功"; 反之,提示 "用户名或者密码错"
-
点击 明文/密文 按钮时,密码框中的内容在明文和密文之间切换
1)点击重置按钮时,将表单内容重置为初始内容
cpp
connect(resetBtn, &QPushButton::clicked, [=](){
accoutTxt->setText("请输入账号");
pwdTxt->setText("请输入密码");
});
2)当用户输入 admin 和 123123 时,提示 "登录成功"; 反之,提示 "用户名或者密码错"
实现思路:
-
点击登录按钮时获取账号框的内容 和 密码框的内容
-
判断 账号框的内容 是否等于 admin 并且 密码框的内容是否等于 123213。
-
相等 提示登录成功
-
不等 提示账号或者密码错
cpp
//1.链接登录按钮的信号和槽
connect(q1,&QPushButton::clicked,[=](){
//2. 获取登录内容
QString e = l1->text() ;
QString e1 = l2->text();
qDebug()<< e << e1;
if(l1->text()=="admin"&&l2->text()=="123456")
{
qDebug() << "登录成功";
}
else {
qDebug() <<"登录失败";
}
});
3)点击修改按钮时,密码框中的内容在明文和密文之间切换
实现思路:
-
头文件中设置 flag 标志, 为 true 时代表此时为密文, 为 false 时代表此时为明文
-
给 明文 \ 密文 按钮添加点击信号
-
信号处理函数( Lambda 表达式)中判断 flag 的值
-
如果为 true,则将 按钮文字改为 密文, 密码框显示明文,flag 改为 false
-
如果为 false,则将 按钮文字改为 明文, 密码框显示密文,flag 改为 true
-
cpp
connect(chgBtn, &QPushButton::clicked, [=](){
flag = !flag;
if (flag == true)
{
pwdLine->setEchoMode(QLineEdit::Password);
chgBtn->setText("明文");
}
else
{
pwdLine->setEchoMode(QLineEdit::Normal);
chgBtn->setText("密文");
}
});
完整代码:
cpp
#include "mywidget.h"
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QDebug>
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
/4.lianxi
//初始化窗口
this->setWindowTitle("游戏登录");
this->setFixedSize(500,300);
QLabel *l = new QLabel;
l->setParent(this);
l->setText("请登录");
l->move(200,50);
QLabel *l1 = new QLabel;
l1->setParent(this);
l1->setText("账号:");
l1->move(100,100);
l1->setFont(QFont("楷体",15,QFont::Black));
QLabel *l2 = new QLabel;
l2->setParent(this);
l2->setText("密码:");
l2->move(100,150);
l2->setFont(QFont("楷体",15,QFont::Black));
l->setFont(QFont("楷体",20,QFont::Black));
l->setAlignment(Qt::AlignHCenter);
QLineEdit *e = new QLineEdit("账号名/手机号/邮箱",this);
e->setPlaceholderText("账号/手机号/邮箱");
QLineEdit *e1 = new QLineEdit("密码",this);
e1->setPlaceholderText("密码");
e1->setEchoMode(QLineEdit::Password);
e->move(180,100);
e1->move(180,150);
e->resize(200,30);
e1->resize(150,30);
QPushButton *q = new QPushButton("重置",this);
QPushButton *q1 = new QPushButton("登录",this);
QPushButton *q2 = new QPushButton("明文",this);
q->move(130,200);
q->resize(50,30);
q1->move(320,200);
q1->resize(50,30);
q2->move(329,150);
q2->resize(50,30);
//任务一:点击"重置"按钮,清空用户表单种填写的内容
//任务二:点击"登录"按钮,得到用户填写的账号和密码验证
// 如果账号为admin,密码为123456时,在控制台输出"登录成功",反之,输出"账号或者密码错误"
//任务三:点击"明文"按钮式,密码框的内容变为明文,按钮文字变为"密文";
// 再次点击时,密码框变为密文,按钮变为"明文"
//1. 链接重置按钮的信号和槽
connect(q,&QPushButton::clicked,[e,e1](){
//2. 清空账号文本框的内容 和 密码框的内容
e->setText("");
e1->clear();
});
//1.链接登录按钮的信号和槽
connect(q1,&QPushButton::clicked,[=](){
//2. 获取登录内容
QString e = l1->text() ;
QString e1 = l2->text();
qDebug()<< e << e1;
if(l1->text()=="admin"&&l2->text()=="123456")
{
qDebug() << "登录成功";
}
else {
qDebug() <<"登录失败";
}
});
//两个状态:
// 密码框是密文,按钮提示明文
// 密码是明文 , 按钮提示密文
//qDebug()<< e1->echoMode() << l2->text();
connect(q2,&QPushButton::clicked,[=](){
if(q2->text()=="明文")
{
e1->setEchoMode(QLineEdit::Normal);
q2->setText("密文");
}
else
{
e1->setEchoMode(QLineEdit::Password);
q2->setText("明文");
}
});
}