Qt从安装到实战项目

转载请注明出处
作者:Alex Yang
配套视频:黑马程序员张涛老师Qt课程
文末配doc笔记文档、源码。

CSDN:杨莫辞
博客园:ycwforeverdoit
哔哩哔哩:故里旧人我在

文章目录

  • 1 下载编辑器
  • 2 创建项目
  • 3 第一个程序
  • 4 工程文件(.pro文件)
  • 5 myWidget头文件
  • 6 常用快捷键
  • 7 QPushButton
    • 7.1 方法一
    • 7.2 方法二
  • 8 对象树
    • 8.1 注意
    • 8.2 对象树的缺陷
    • 8.3 总结析构顺序
    • 8.4 迷惑
    • 8.5 针对上述,我们可以
  • 9 坐标系
  • 10 信号和槽
    • 10.1 连接函数connect
    • 10.2 系统提供的信号和槽
    • 10.3 自定义信号和槽
    • 10.4 重载信号和槽
    • 10.5 信号连接信号
    • 10.6 断开信号
    • 10.7 拓展
  • 11 lambda表达式
  • 12 QMainWindows
  • 13 资源文件
  • 14 对话框
    • 14.1 模态对话框和消息对话框
    • 14.2 标准对话框
  • 15 UI控件
    • 15.1 按钮
    • 15.2 ItemWidget
    • 15.3 其它控件
    • 15.4 封装自定义组合控件
  • 16 事件
    • 16.1 鼠标事件
    • 16.2 定时器事件
    • 16.3 事件分发器
    • 16.4 事件过滤器
    • 16.5 绘图事件
    • 16.6 绘图高级设置
    • 16.7 手动调用绘图事件
    • 16.8 绘图设备QPainterDevice
  • 17 文件读写QFile
    • 17.1 读文件
    • 17.2 写文件
  • 18 文件信息
  • 19 实战
    • 19.1 创建项目、添加资源
    • 19.2 UI设置
    • 19.3 窗口设置
    • 19.4 菜单栏菜单项设置
    • 19.5 设置背景图片
    • 19.6 创建按钮类
    • 19.7 按钮移动特效
    • 19.8 选择关卡类
    • 19.9 设置选择关卡窗口
    • 19.10 返回按钮按下效果
    • 19.11 返回按钮功能实现
    • 19.12 创建关卡选择按钮
    • 19.13 关卡标签
    • 19.14 穿透事件
    • 19.15 翻金币场景设置
    • 19.16 场景内容功能设置
    • 19.17 关卡场景中显示关卡数
    • 19.18 创建金币背景
    • 19.19 金币类
    • 19.20 配置关卡数据
    • 19.21 根据数据创建金币银币
    • 19.22 金币翻转特效
    • 19.23 提升用户体验
    • 19.24 周围金币翻转
    • 19.25 判断胜利
    • 19.26 胜利图片显示
    • 19.27 添加开始按钮音效
    • 19.28 设置窗口切换时保持在原位置
    • 19.29 项目打包

1 下载编辑器

QT是跨平台图形界面引擎。
优点:跨平台、接口简单、一定程度简化内存回收。
创建:1991奇趣科技
案例:Linux桌面环境KDE、谷歌地图、VLC多媒体播放器

**安装步骤跳转到主页对应blog**

2 创建项目

注意:项目路径及项目名称不能为中文、不能有空格

Qt从安装到实战项目_第1张图片

位置:顾名思义

Qt从安装到实战项目_第2张图片

构建套件:选择用什么开发。用什么版本

Qt从安装到实战项目_第3张图片

详情:创建一个主窗口类(下图myWidget),QWidget是空窗口,QMainWindow多了菜单栏、状态栏,Qdialog有选择性的物件(如下图对话框的下一步按钮),它们三者是继承关系。

创建界面复选框:勾选则要进行界面UI设计,否则就只是像dev一样实现逻辑。

Qt从安装到实战项目_第4张图片

汇总:团队开发时,将团队成员各自的代码,使用版本控制系统svn、vss或git。

Qt从安装到实战项目_第5张图片

3 第一个程序

Qt从安装到实战项目_第6张图片

QApplication a:创建应用程序对象,名为a,有且仅有一个 myWidget w:实例化窗口对象 w.show():显示窗口
return a.exec():让应用程序对象进入消息循环机制,代码阻塞当前行(窗口不会一闪而过,会一直等待用户操作)

4 工程文件(.pro文件)

Qt从安装到实战项目_第7张图片

(1)第7行:包含的模块,core是核心模块,gui是图形模块,QT所有模块如下

Qt从安装到实战项目_第8张图片

(2)第9行:  greaterThan表示大于  (QT_MAJOR_VERSION, 4)表示版本为4  QT +=
widgets同理第7行表示包含widgets模块。  整行表示“版本大于4就包含widgets模块”。

(3)第11行:生成exe文件的名称为01FirstProject,路径如下

Qt从安装到实战项目_第9张图片

(4)第12行:模板变量告诉qmake为这个应用程序生成哪种makefile。下面是可选择的模板
 app:建立一个应用程序的makefile。这是默认值,所以如果模板没有被指定,这个将被使用。
 lib:建立一个库的makefile。
 vcapp:建立一个应用程序的VisualStudio项目文件。
 vclib:建立一个库的VisualStudio项目文件。
 Subdirs:特殊的模板,可以创建一个能够进入特定目录并且为一个项目文件生成makefile并且为它调用make的makefile。

(5)第15-16行:项目生成的源文件,在外部创建新文件编译器会在pro文件中该位置后自动增加添加的文件。或者直接在pro文件中该位置后增加文件,保存后外部也会自动创建增加的文件。(注意文件间用“\”分割)

(6)第18行:同上,这里是头文件。

5 myWidget头文件

Qt从安装到实战项目_第10张图片

(1)第1-2、15行:防止重复包含

(2)第4行:QWidget窗口类头文件

(3)第8行:Q_OBJECT宏,有了这个才允许类中使用信号和槽机制

6 常用快捷键

1)注释    ctrl  +  /2)运行    ctrl  +  r
(3)编译    ctrl  +  b
(4)字体缩放    ctrl  +  鼠标滚轮
(5)查找    ctrl  +  f
(6)整行移动    ctrl  +  shift  +  ↑或↓
(7)帮助文档    F1或左侧“帮助”或
(8)自动对齐    ctrl  +  i
(9)同名.h和.cpp切换    F4

7 QPushButton

7.1 方法一

Qt从安装到实战项目_第11张图片

使用顶层方法show如下:

Qt从安装到实战项目_第12张图片

绑定父窗口如下:

Qt从安装到实战项目_第13张图片

按钮显示文本:

Qt从安装到实战项目_第14张图片
Qt从安装到实战项目_第15张图片

7.2 方法二

局限是创建的myWidget窗口大小配对按钮大小,所以这里创建出来的窗口大小很小

Qt从安装到实战项目_第16张图片
Qt从安装到实战项目_第17张图片

可以手动调整大小(按钮也可以调整大小):

Qt从安装到实战项目_第18张图片

移动按钮在父窗口中的位置:

Qt从安装到实战项目_第19张图片
Qt从安装到实战项目_第20张图片

设置窗口标题:

Qt从安装到实战项目_第21张图片
Qt从安装到实战项目_第22张图片

设置固定大小,用户不可以改变窗口大小:

Qt从安装到实战项目_第23张图片

8 对象树

(1)可以看到上述代码中,new的对象没有手动释放,其原理就是对象树。

(2)下图是一个对象树,win是窗口,Topic、obj是小控件。

Qt从安装到实战项目_第24张图片

8.1 注意

① 不是继承关系中的子类父类。这里的措辞是对象,指对象与对象之间的树状关系,是父对象与子对象的关系。
② 一个父对象可以包含多个子对象,但一个子对象只有一个父对象(原理:根据下图Qt帮助文档可知)

Qt从安装到实战项目_第25张图片

③ 指定父对象(如btn->setParent(this),创建的这个QObject对象btn自动添加到父对象的children()列表)后,子对象就不需要手动释放。未指定的需要手动释放,否则出现内存泄露。
④ 当父对象析构时,其子对象列表children()中所有的对象被析构。当子对象先析构时,子对象自动从父对象的children()列表删除。

堆区:首先delete掉对应对象空间,其子对象按顺序调用析构函数,父对象析构函数不会再调用,如下图

Qt从安装到实战项目_第26张图片

栈区:不允许delete

⑤ 析构≠释放。这里要和C++区分:在C++中,不存在继承关系时,按照创建顺序,先创建的先构造,先构造的后析构,如下图

Qt从安装到实战项目_第27张图片

存在继承关系时,父类先构造,后析构,如下图

Qt从安装到实战项目_第28张图片

在Qt中,不存在对象树时,构造析构顺序和C++不存在继承关系时一样,按照创建顺序,先创建的先构造,先构造的后析构。存在对象树时,若在堆开辟空间,则先创建的先构造先析构,唯一要注意的就是销毁过程相反(即执行某个QObject对象的析构函数时还没有释放内存,在析构函数结束时才释放,这里常常产生错觉);若在栈开辟空间,则先创建后释放。如下图,

堆区:

Qt从安装到实战项目_第29张图片

栈区:

Qt从安装到实战项目_第30张图片

⑥ 正常情况(不使用delete、无父对象子对象创建顺序问题)栈区内存释放过程:先创建后析构。

Qt从安装到实战项目_第31张图片

⑦ 正常情况堆区内存释放过程:用下图案例说明,从根节点开始(即最顶层父对象w1),程序中w1.show()显示窗口(w2、w3、w4包含在里面),这时候点击关闭按钮触发w1窗口的close()槽,进入w1的析构函数,首先执行w1析构函数内的qDebug()宏,输出信息“w1析构”(注意这时候w1还没有被释放),接着查看w1是否有子对象,发现有子对象w2,则继续进入w2的析构函数,输出信息“w2析构”,同理,进入w3析构函数,输出信息“w3析构”,最后进入w4的析构函数,输出信息“w4析构”,发现w4没有子对象,开始回走,首先结束w4析构函数,这时候才释放w4内存空间,接着释放w3,…,直到释放完全。如下图

Qt从安装到实战项目_第32张图片

⑧ QWidget是QObject的子类,在parent机制上无区别,但在实际使用时QWidget更复杂,原因是QWidget和QEventLoop高度配合才能完成工作。实际中,QWidget的关闭流程,首先用户点击关闭按钮触发close()槽,然后Qt向widget发送QCloseEvent,默认的QCloseEvent(用户没有重写,使用默认)将widget隐藏起来,即hide()。所以,通过QWidget关闭流程可知,Widget关闭的实质是隐藏,而没有释放内存。因此,需要设置Qt::WA_DeleteOnClose属性,使得close后调用widget的析构函数,另外一种就是直接手动delete。

8.2 对象树的缺陷

①上面说到先构造后析构(C++原理),即先创建后析构。有一种情况,先创建子对象,后创建父对象。对于在栈区开辟空间的情况,根据第一句所说则应该先析构父对象,又遵从Qt对象树原理,则其子对象随之被析构,代码继续执行,按照第一句所说则会再析构一次子对象,这时出现对同一对象调用两次析构函数的情况,而C++中不允许重复调用两次析构函数,因此程序崩溃。如下图,关闭w1后程序crush

Qt从安装到实战项目_第33张图片

对于在堆区开辟空间的情况:子对象和父对象的创建先后无影响

Qt从安装到实战项目_第34张图片

②由注意的④可知delete很危险。

8.3 总结析构顺序

①使用delete:
	堆区:delete的对象及其所有子对象,按顺序从父对象到子对象调用析构函数。(与创建顺序无关)
	栈区:不允许delete。
②先创建子对象,后创建父对象:
	堆区:先创建先析构,但最后释放内存,也就是先析构子对象。
	栈区:不允许,应用程序crush。
③正常情况(不使用delete、无父对象子对象创建顺序问题):
	堆区:先析构父对象,但子对象先释放内存。
	栈区:先创建后析构,也可以理解为先析构子对象后析构父对象,析构的同时释放内存。

8.4 迷惑

不要把Qt和C++完全等比,正常情况下在堆区开辟的对象,其析构函数被调用时不会释放对象空间,即先创建的先调用析构函数,但是最后释放(等调用到最底层子对象结束后开始往回走,一个一个结束析构函数,这时候才真正的释放内存)。

8.5 针对上述,我们可以

①先创建父对象后创建子对象
②在堆上创建对象
③不要对指定了父对象的对象delete

9 坐标系

坐标系是相对父窗口而言的。

Qt从安装到实战项目_第35张图片

10 信号和槽

10.1 连接函数connect

格式:connect(信号发送者,信号,信号接收者,处理的槽函数)

注意:信号和槽函数都是函数地址

信号槽优点:松散耦合(信号发送端和接收端是独立无关联的,只不过是通过connect将两端耦合联系起来,即信号端的操作成功与否和接收端无关,信号端成功发送信号给接收端,接收端也不一定成功处理)

10.2 系统提供的信号和槽

案例:关闭窗口,如下图

Qt从安装到实战项目_第36张图片

10.3 自定义信号和槽

(1)信号函数:
①返回值是 void
②只需要声明,不需要实现
③可以有参数
④写在signals下

(2)槽函数:
①返回值是void
②需要声明,需要实现
③可以有参数
④早期Qt版本必须写在publicslots下,高级版本可以写到public或全局下

Qt从安装到实战项目_第37张图片

(3)流程:
①定义两个操作类,一个作为信号发送者类,一个作为信号接收者类
②信号发送者类中,在signals下定义信号函数
③信号接收者类中,在public lots下定义槽函数
④定义触发函数,触发函数中触发信号
⑤在主调函数中,创建信号发送者和信号接收者(信号发送者类和信号接收者类的对象)
⑥使用connect函数连接发送者和接收者
⑦调用触发函数

(4)案例:
①信号发送者:学生
②信号:犯错
③信号接收者:老师
④槽:批评

Qt从安装到实战项目_第38张图片
Qt从安装到实战项目_第39张图片
Qt从安装到实战项目_第40张图片
Qt从安装到实战项目_第41张图片
Qt从安装到实战项目_第42张图片
Qt从安装到实战项目_第43张图片
Qt从安装到实战项目_第44张图片

10.4 重载信号和槽

信号函数重载、触发函数重载(触发函数不一定写在信号发送者类中)

Qt从安装到实战项目_第45张图片

槽函数重载

Qt从安装到实战项目_第46张图片

槽函数实现

Qt从安装到实战项目_第47张图片

因为重载,所以连接时不能够直接取函数地址,要使用函数指针

Qt从安装到实战项目_第48张图片

运行结果

Qt从安装到实战项目_第49张图片

可以看到上图运行结果外多了一个引号,这是因为传的是QString,将QString转为char就可以了,方法是先通过.toUtf8()转成QByteArray,再通过.data()转成char

Qt从安装到实战项目_第50张图片

改为事件触发信号连接

Qt从安装到实战项目_第51张图片

10.5 信号连接信号

案例:按钮点击信号,连接到学生犯错信号,学生犯错信号连接到老师批评槽函数,达到传递效果。

注意:信号和槽参数必须保持一致。

Qt从安装到实战项目_第52张图片

10.6 断开信号

同理connect,断开信号使用disconnect。

10.7 拓展

①一个信号,可以连接多个槽函数
②多个信号,可以连接同一个槽函数
③信号和槽函数,参数类型不许一一对应
④信号和槽函数,信号的参数个数可以多于槽函数,反之不可
⑤Qt4版本以前,信号和槽连接方式,如
connect(st,SIGNAL(mistake()),te,SLOT(criticize()));
底层原理:将SIGNAL(mistake())和SLOT(criticize())中的mistake()和criticize()转换为字符串”mistake()”和”criticize()”然后去寻找。
Qt4版本优点:参数直观
缺点:类型不做检测
⑥Qt5以上版本支持Qt4版本写法

11 lambda表达式

实质:匿名函数,是C++11的新特性,低版本需要在工程文件中添加 CONFIG += C++11

格式:[ 函数对象参数 ] (操作符重载函数参数)mutable->返回值{函数体}。

(1) Mutable->返回值:根据需要添加,最基本的部分就是{}
(2) 函数对象参数:

①	空。无任何函数对象参数。
②	=。函数体内可以使用lambda所在作用范围内的所有可见的局部变量(包括lambda所在类的this)。并且是值传递方式。
③	&。同上,是引用传递方式。
④	this。函数体内可以使用lambda所在类中的成员变量。
⑤	a。将a按值传递,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const,要修改传递进来的a的拷贝可以添加mutable修饰符。
⑥	&a。按引用传递。
⑦	a,&b。a按值传递,b按引用传递。
⑧	=,&a,&b。除了a和b按引用传递,其它参数都按值传递。
⑨	&,a,b。除了a和b按值传递,其它参数都按引用传递。

(3) 操作符重载函数参数:标识重载的()操作符的参数,没有参数时省略。参数可以通过按值传递(如:(a,b))和按引用传递(如:(&a,&b))。
(4) 可修改标识符(mutable):注意添加mutable后能修改的是拷贝,而不是值本身。
(5) 函数返回值(->返回值类型):返回值为void或函数体中只有一处return时,可以省略。
(6) 函数体:无实现时为空,但{}不可省略。
(7) 注意:区分下面两种
Qt从安装到实战项目_第53张图片

12 QMainWindows

QMainWindows是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个链接部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget)。如下图

Qt从安装到实战项目_第54张图片

(1)创建菜单栏
menuBar()是函数,函数系统源码内已经创建了对象树,所以这里可以直接调用这个menuBar()函数,而不需要new

Qt从安装到实战项目_第55张图片

(2)菜单栏放入窗口,这时候还看不到

Qt从安装到实战项目_第56张图片

(3)创建菜单

Qt从安装到实战项目_第57张图片

(4)创建菜单项

Qt从安装到实战项目_第58张图片
Qt从安装到实战项目_第59张图片

(5)创建工具栏,工具栏可以拖拽到任意位置

Qt从安装到实战项目_第60张图片
Qt从安装到实战项目_第61张图片

(6)更改工具栏默认位置(Qt::是枚举值)

Qt从安装到实战项目_第62张图片
Qt从安装到实战项目_第63张图片

(7)设置只允许左右停靠

Qt从安装到实战项目_第64张图片

(8)设置浮动、设置移动

Qt从安装到实战项目_第65张图片

(9)设置工具项,也可以设置分割线(未演示)

Qt从安装到实战项目_第66张图片

(10)增加按钮

Qt从安装到实战项目_第67张图片

(11)创建状态栏

Qt从安装到实战项目_第68张图片

(12)放标签控件

Qt从安装到实战项目_第69张图片

(13)逆序放标签控件

Qt从安装到实战项目_第70张图片

(14)创建铆接部件、主体部件,铆接部件又叫浮动部件,铆接部件可以设置停靠区域

Qt从安装到实战项目_第71张图片

13 资源文件

(1)建立可以UI设计的项目

Qt从安装到实战项目_第72张图片

(2)UI设计,可以直接拖拽组件

Qt从安装到实战项目_第73张图片
Qt从安装到实战项目_第74张图片
Qt从安装到实战项目_第75张图片
Qt从安装到实战项目_第76张图片
Qt从安装到实战项目_第77张图片

(2)添加icon,首先把icon文件资源复制到项目文件夹,然后新建Qt文件资源文件

Qt从安装到实战项目_第78张图片
Qt从安装到实战项目_第79张图片
Qt从安装到实战项目_第80张图片
Qt从安装到实战项目_第81张图片
Qt从安装到实战项目_第82张图片
Qt从安装到实战项目_第83张图片
Qt从安装到实战项目_第84张图片
Qt从安装到实战项目_第85张图片
Qt从安装到实战项目_第86张图片

14 对话框

14.1 模态对话框和消息对话框

模态对话框:弹出对话框后,不能对其它窗口操作
非模态对话框:可以对其它窗口操作

Qt从安装到实战项目_第87张图片
Qt从安装到实战项目_第88张图片
Qt从安装到实战项目_第89张图片
Qt从安装到实战项目_第90张图片

14.2 标准对话框

Qt内置对话框:
 QColorDialog 选择颜色
 QFileDialog 选择文件或目录
 QFontDialog 选择字体
 QInputDialog 允许用户输入一个值,并返回该值
 QMessageBox 模态对话框,用于显示信息,询问问题等
 QPageSetupDialog 为打印机提供纸张相关的选项
 QPrintDialog 打印机配置
 QPrintPreviewDialog 打印预览
 QProgressDialog 显示操作过程

Qt从安装到实战项目_第91张图片
Qt从安装到实战项目_第92张图片
Qt从安装到实战项目_第93张图片
Qt从安装到实战项目_第94张图片
Qt从安装到实战项目_第95张图片
Qt从安装到实战项目_第96张图片
Qt从安装到实战项目_第97张图片

15 UI控件

15.1 按钮

Qt从安装到实战项目_第98张图片

普通按钮PushButton

图片按钮(又叫工具按钮)ToolButton,用于显示图片,如果想显示文字,修改属性tooButtonStyle,想凸起,修改属性autoRaise

复选框RadioButton,如果多个复选框要分组,添加控件GroupBox,如果要设置默认选中,在逻辑代码中ui->复选框名->setChecked(true)

多选框CheckBox,监听状态(是否选中,返回对应值)下,选中返回2,半选返回1,未选返回0

15.2 ItemWidget

Qt从安装到实战项目_第99张图片
Qt从安装到实战项目_第100张图片
Qt从安装到实战项目_第101张图片
Qt从安装到实战项目_第102张图片

列表控件QListWidget:
 QListWidgetItem * item = new QListWidgetItem (“内容”);
 ui->列表容器名->addItem(item);
 设置居中方式 item->setTextAlignment(枚举值);
 添加多行 addItems(一个列表)

树控件QTreeWidget:
 设置头 ui ->树容器名->setHeaderLabels(一个列表);
 创建根节点 QTreeWidgetItem * listItem = new QTreeWidgetItem(“内容”);
 添加根节点 ui->树容器名->addTopLevelItem(listItem);
 创建子节点 QTreeWidgetItem * l1 = new QTreeWidgetItem(一个列表);
 添加子节点 listItem -> addChild(l1);

表格控件QTableWidget:
 设置列数 ui -> 表格控件名 -> setColumnCount(总列数);
 设置水平表头 ui -> 表格控件名 -> setHorizontalHeaderLabels(表头列表);
 设置行数 ui -> 表格控件名 -> setRowCount(总行数);
 设置正文 ui -> 表格控件名 -> setItem(行数,列数,元素);

15.3 其它控件

Qt从安装到实战项目_第103张图片
Qt从安装到实战项目_第104张图片
Qt从安装到实战项目_第105张图片

通过按钮控制不同页的跳转:ui->tabwidget名->setCurrentIndex(页号);

Qt从安装到实战项目_第106张图片
Qt从安装到实战项目_第107张图片
Qt从安装到实战项目_第108张图片
Qt从安装到实战项目_第109张图片
Qt从安装到实战项目_第110张图片
Qt从安装到实战项目_第111张图片
Qt从安装到实战项目_第112张图片

15.4 封装自定义组合控件

(1)新建设计师界面文件

Qt从安装到实战项目_第113张图片
Qt从安装到实战项目_第114张图片
Qt从安装到实战项目_第115张图片
Qt从安装到实战项目_第116张图片

(2)在新建的封装类的ui中,设计要封装的组合控件

Qt从安装到实战项目_第117张图片

(3)回到呈现类的ui设计

Qt从安装到实战项目_第118张图片
Qt从安装到实战项目_第119张图片
Qt从安装到实战项目_第120张图片
Qt从安装到实战项目_第121张图片
Qt从安装到实战项目_第122张图片

(4)封装空间的逻辑在封装类中实现,本案例实现数字选择框和滑动条联动(滑动条变化则数字选择框变化,反之亦然)

Qt从安装到实战项目_第123张图片
Qt从安装到实战项目_第124张图片
Qt从安装到实战项目_第125张图片
Qt从安装到实战项目_第126张图片

16 事件

QEvent是事件

16.1 鼠标事件

 进入事件 enterEvent
 离开事件 leaveEvent
 按下事件 mousePressEvent(QMouseEvent ev)
 释放事件 mouseReleaseEvent
 移动事件 mouseMoveEvent
 X坐标 ev->x()
 Y坐标 ev->y()
 全局x坐标(相对于整个屏幕) ev->globalX()
 全局y坐标 ev->globalY()
 判断鼠标是哪个键被点击 ev->button() 左键Qt::LeftButton Qt::RightButton
 判断组合键(鼠标两个以上键同时点击) ev->buttons()
 格式化字符串 QString(%1 %2).arg(显示到1位置的内容).arg(显示到2位置的内容)

16.2 定时器事件

(1)查帮助文档

Qt从安装到实战项目_第127张图片

(2)添加两个标签

Qt从安装到实战项目_第128张图片

(3)重写timerEvent函数,启动计时器

Qt从安装到实战项目_第129张图片

(4)多个计时器

Qt从安装到实战项目_第130张图片
Qt从安装到实战项目_第131张图片
Qt从安装到实战项目_第132张图片

(5)利用计时器类QTimer(停止计时的接口是timer->stop())

Qt从安装到实战项目_第133张图片

16.3 事件分发器

bool event(QEvent * e)可以用于事件分发,也可用于事件拦截

Qt从安装到实战项目_第134张图片

重写bool event(QEvent * e)函数,在函数中利用if等判断语句,若用户操作为if判断的操作,则执行if语句内的代码,然后return true,则事件分发器不在向下分发,若未执行if语句代码,则return QLabel::event()或其它,即依旧让系统进行事件分发,交给父类事件分发器进行。

16.4 事件过滤器

在用户操作和事件分发器中间还有一个事件过滤器,同理事件分发器,事件过滤器内用户也可以自己处理某事件,剩下的交给父类事件过滤器处理。

第一步,安装事件过滤器 ui->控件名->installEventFilter(this)
第二步,重写事件过滤器 void eventFilter(QObject*,QEvent*),函数内先判断控件(可能有多个控件安装了事件过滤器,但只有这一个函数使用),然后判断事件(同理事件分发器)

Qt从安装到实战项目_第135张图片

16.5 绘图事件

Qt的绘图系统基于QPainter,QPaintDevice和QPaintEngine三个类。

QPainter用来绘制。
QPaintDevice是一个二维空间的抽象,这个二维空间是QPainter的工作空间。
QPaintEngine提供QPainter在不同设备上绘制的统一接口。

在这里插入图片描述
Qt从安装到实战项目_第136张图片
Qt从安装到实战项目_第137张图片
Qt从安装到实战项目_第138张图片
Qt从安装到实战项目_第139张图片
Qt从安装到实战项目_第140张图片

16.6 绘图高级设置

(1)提高清晰度

在这里插入图片描述
Qt从安装到实战项目_第141张图片

(2)转移绘图圆点

Qt从安装到实战项目_第142张图片

如果在第二个矩形后再加一个画矩形的语句,再次画的矩形也是相对这个新绘图原点画。

(3)保存/恢复绘图状态
使用恢复时必须已经保存绘图状态,恢复可以还原到保存的状态

Qt从安装到实战项目_第143张图片

16.7 手动调用绘图事件

(1)画照片

Qt从安装到实战项目_第144张图片

(2)手动调用
先创建一个按钮,然后利用connect连接绘图事件和按钮事件,手动调用绘图事件不能直接调用paintEvent(QPaintEvent*),旧版本使用repaint(),新版本使用更优的update()

Qt从安装到实战项目_第145张图片

(3)移动图像与计时器结合

Qt从安装到实战项目_第146张图片

16.8 绘图设备QPainterDevice

绘图设备有QPixmap、QImage、QBitmap(只有黑白色)、QPicture、QWidget。

(1)QPixmap 对不同平台做了显示的优化

绘制图像:
 第一步:创建pixmap图像对象QPixmap pix(长,宽)
 第二步:填充颜色(最后生成的图像默认背景为黑色,修改背景填充颜色)pix.fill(颜色)
 第三步:创建画笔QPainter painter(&pix)
 第四步:利用画笔在图像对象pix上绘画(见16.5)
 第五步:保存图像pix.save(路径)

Qt从安装到实战项目_第147张图片
Qt从安装到实战项目_第148张图片
Qt从安装到实战项目_第149张图片
Qt从安装到实战项目_第150张图片

(2)QImage 可以对像素点进行修改

绘制图像:
 第一步:创建image图像对象QImage img(长,宽,颜色类型)
 第二步:其它和QPixmap相同

修改像素点:
 第一步:创建image图像图像QImage img
 第二步:加载图片(只能是添加到资源文件的图片)img.load(文件路径)
 第三步:设置修改后的图像颜色QRgb value = qRgb(255,0,0)
 第四步修改img.setPixel(像素点x,像素点y,value)

Qt从安装到实战项目_第151张图片
Qt从安装到实战项目_第152张图片

下图只能写在绘图事件中,不能写在其它位置

Qt从安装到实战项目_第153张图片

(3)QPicture 记录和重现图像

记录图像:
 第一步:创建picture图像对象QPicture pic
 第二步:创建画笔QPainter painter
 第三步:利用画笔在图像对象pic上绘画painter.begin(&pic)
 第四步:结束绘图painter.end()
 第五步:保存(任意后缀名)pic.save(路径)

重现图像(有些图像正常不能打开,如zt后缀图像,所以要用代码打开):
 第一步:创建画笔QPainter painter(this)
 第二步:创建pic对象QPicture pic
 第三步:关联文件pic.load(文件路径)
 第四步:利用画笔painter.drawPicture(重现位置x,重现位置y, pic)

Qt从安装到实战项目_第154张图片
Qt从安装到实战项目_第155张图片

17 文件读写QFile

17.1 读文件

Qt从安装到实战项目_第156张图片
Qt从安装到实战项目_第157张图片
Qt从安装到实战项目_第158张图片
Qt从安装到实战项目_第159张图片

上述操作后记得关闭文件,上面忘记关闭了:file.close()

17.2 写文件

Qt从安装到实战项目_第160张图片

18 文件信息

Qt从安装到实战项目_第161张图片
Qt从安装到实战项目_第162张图片
Qt从安装到实战项目_第163张图片

19 实战

实战项目:翻金币游戏。

19.1 创建项目、添加资源

创建QMainWindow项目,添加图片、图标、音效资源,完成后如下

Qt从安装到实战项目_第164张图片

19.2 UI设置

删除工具栏、导航栏,菜单栏添加菜单项,完成后如下

Qt从安装到实战项目_第165张图片

19.3 窗口设置

设置窗口固定大小、窗口图标、窗口标题,完成后如下

Qt从安装到实战项目_第166张图片

19.4 菜单栏菜单项设置

菜单项“退出”功能实现,完成后如下

Qt从安装到实战项目_第167张图片

19.5 设置背景图片

先设置背景主图片占满整个窗口,再添加一个背景标题图片,覆盖在主图片上左上角,完成后如下

Qt从安装到实战项目_第168张图片
Qt从安装到实战项目_第169张图片

19.6 创建按钮类

Qt从安装到实战项目_第170张图片
Qt从安装到实战项目_第171张图片
Qt从安装到实战项目_第172张图片
Qt从安装到实战项目_第173张图片
Qt从安装到实战项目_第174张图片

19.7 按钮移动特效

Qt从安装到实战项目_第175张图片
Qt从安装到实战项目_第176张图片
Qt从安装到实战项目_第177张图片
Qt从安装到实战项目_第178张图片

19.8 选择关卡类

创建选择关卡窗口类,关联开始按钮和选择关卡窗口,完成后如下

Qt从安装到实战项目_第179张图片
Qt从安装到实战项目_第180张图片

19.9 设置选择关卡窗口

设置选择关卡窗口内容,设置窗口背景,添加按钮,完成后如下

Qt从安装到实战项目_第181张图片
Qt从安装到实战项目_第182张图片

19.10 返回按钮按下效果

在按钮类中重写鼠标按下释放事件,完成后如下

Qt从安装到实战项目_第183张图片
Qt从安装到实战项目_第184张图片

19.11 返回按钮功能实现

利用信号和槽实现场景切换,完成后如下

Qt从安装到实战项目_第185张图片
Qt从安装到实战项目_第186张图片
Qt从安装到实战项目_第187张图片
Qt从安装到实战项目_第188张图片

19.12 创建关卡选择按钮

利用循环创建按钮,完成后如下

Qt从安装到实战项目_第189张图片
Qt从安装到实战项目_第190张图片

19.13 关卡标签

同样利用循环创建标签覆盖在按钮上,完成后如下

Qt从安装到实战项目_第191张图片
Qt从安装到实战项目_第192张图片

19.14 穿透事件

因为标签覆盖了按钮,导致按钮无法生效,设置穿透,使得鼠标可以触发按钮(即标签变成类似透明),完成后如下

Qt从安装到实战项目_第193张图片
Qt从安装到实战项目_第194张图片

19.15 翻金币场景设置

首先创建一个类,接着使用自定义构造函数进行窗口、背景、按钮配置,完成后如下

Qt从安装到实战项目_第195张图片
Qt从安装到实战项目_第196张图片

19.16 场景内容功能设置

实现退出菜单项、返回按钮功能,完成后如下

Qt从安装到实战项目_第197张图片
Qt从安装到实战项目_第198张图片
Qt从安装到实战项目_第199张图片

19.17 关卡场景中显示关卡数

在关卡场景类的构造函数中定义标签控件,设置字体格式,标签装备字体格式,设置标签显示字体,调整标签位置,完成后如下

Qt从安装到实战项目_第200张图片

19.18 创建金币背景

利用标签和循环显示金币背景,完成后如下

Qt从安装到实战项目_第201张图片

19.19 金币类

创建金币类,并创建金币,完成后如下

在这里插入图片描述
Qt从安装到实战项目_第202张图片

19.20 配置关卡数据

创建文件,通过map和vector容器将每一关的数据保存,完成后如下

Qt从安装到实战项目_第203张图片
Qt从安装到实战项目_第204张图片

19.21 根据数据创建金币银币

在游戏场景文件中,创建数据对象,将数据对象的数据拷贝给游戏场景数组,在循环中按数据创建金币银币,完成后如下

Qt从安装到实战项目_第205张图片Qt从安装到实战项目_第206张图片

Qt从安装到实战项目_第207张图片

19.22 金币翻转特效

在金币类创建定时器、金币标志、金币参数,在金币类中定义点击金币函数,函数内根据金币标志调用定时器开始计时,金币类构造函数中连接定时器计时事件和要实现的内容,在游戏场景中连接点击金币和点击金币函数,完成后如下

Qt从安装到实战项目_第208张图片

Qt从安装到实战项目_第209张图片

Qt从安装到实战项目_第210张图片

19.23 提升用户体验

在金币类中,定义一个特效执行标志,用来判断特效是否执行完成,然后在对应位置改变其值,重写鼠标点击事件,若特效还在执行则直接返回知道执行完成,从而达到第一次翻完才能翻第二次的效果,提升用户体验,完成后如下

Qt从安装到实战项目_第211张图片
Qt从安装到实战项目_第212张图片
Qt从安装到实战项目_第213张图片
Qt从安装到实战项目_第214张图片

19.24 周围金币翻转

在金币类中,定义金币位置变量,游戏场景中,定义金币状态数组,在创建金币前赋值相应数据,在连接处判断周围情况,实现翻转,最后优化,让周围金币延时翻转,完成后如下

Qt从安装到实战项目_第215张图片
Qt从安装到实战项目_第216张图片
Qt从安装到实战项目_第217张图片
Qt从安装到实战项目_第218张图片
Qt从安装到实战项目_第219张图片

19.25 判断胜利

在金币类和游戏场景中添加胜利标志isWin,每次点击金币翻金币后双层循环依次判断每一个金币状态flag,如果全部变为金币则isWin为真,此时将金币类的isWin也赋值为真,在鼠标点击事件中判断如果isWin为真则直接return,即不能再翻金币,完成后如下

Qt从安装到实战项目_第220张图片
Qt从安装到实战项目_第221张图片
Qt从安装到实战项目_第222张图片
Qt从安装到实战项目_第223张图片

19.26 胜利图片显示

首先创建胜利图片,然后在判断胜利的语句中让胜利图片显示,完成后如下

Qt从安装到实战项目_第224张图片
Qt从安装到实战项目_第225张图片

19.27 添加开始按钮音效

在工程文件添加音效模块multimedia,再在要使用的地方包含头文件、创建音效、播放 音效,完成后如下

Qt从安装到实战项目_第226张图片
Qt从安装到实战项目_第227张图片
Qt从安装到实战项目_第228张图片

19.28 设置窗口切换时保持在原位置

格式:即将显示的窗口->setGeometry(当前窗口->geometry())。

19.29 项目打包

首先按release编译,随后文件夹生成一个release文件夹

Qt从安装到实战项目_第229张图片
Qt从安装到实战项目_第230张图片

新建文件夹,将release中的exe文件复制到新建文件夹

Qt从安装到实战项目_第231张图片
Qt从安装到实战项目_第232张图片

保证qt安装路径bin有下图文件,打开cmd,进入新建文件夹,输入图中内容,等待片刻就生成了很多文件

在这里插入图片描述

Qt从安装到实战项目_第233张图片

若要打包成安装包,则使用HM NIS Edit软件按步骤打包即可。

「Qt从下载 到实战」https://www.aliyundrive.com/s/gcHge1y6Zun
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。

你可能感兴趣的:(Qt,qt,ui,开发语言)