转载请注明出处
作者: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 创建项目

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

位置:顾名思义

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

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

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

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

3 第一个程序

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

4 工程文件(.pro文件)

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

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

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

(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头文件

(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 方法一

使用顶层方法show如下:

绑定父窗口如下:

按钮显示文本:


7.2 方法二

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


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


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


设置窗口标题:


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

8 对象树

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

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

8.1 注意

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

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

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

栈区:不允许delete

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

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

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

堆区:

栈区:

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

⑦ 正常情况堆区内存释放过程:用下图案例说明,从根节点开始(即最顶层父对象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,…,直到释放完全。如下图

⑧ 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

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

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

8.3 总结析构顺序

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

8.4 迷惑

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

8.5 针对上述,我们可以

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

9 坐标系

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

10 信号和槽

10.1 连接函数connect

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

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

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

10.2 系统提供的信号和槽

案例:关闭窗口,如下图

10.3 自定义信号和槽

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

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

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

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







10.4 重载信号和槽

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

槽函数重载

槽函数实现

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

运行结果

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

改为事件触发信号连接

10.5 信号连接信号

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

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

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) 注意:区分下面两种

12 QMainWindows

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

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

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

(3)创建菜单

(4)创建菜单项


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


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


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

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

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

(10)增加按钮

(11)创建状态栏

(12)放标签控件

(13)逆序放标签控件

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

13 资源文件

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

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





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









14 对话框

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

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




14.2 标准对话框

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







15 UI控件

15.1 按钮

普通按钮PushButton

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

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

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

15.2 ItemWidget




列表控件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 其它控件



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







15.4 封装自定义组合控件

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




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

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





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




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)查帮助文档

(2)添加两个标签

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

(4)多个计时器



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

16.3 事件分发器

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

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

16.4 事件过滤器

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

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

16.5 绘图事件

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

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






16.6 绘图高级设置

(1)提高清晰度


(2)转移绘图圆点

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

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

16.7 手动调用绘图事件

(1)画照片

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

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

16.8 绘图设备QPainterDevice

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

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

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




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

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

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


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

(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)


17 文件读写QFile

17.1 读文件




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

17.2 写文件

18 文件信息



19 实战

实战项目:翻金币游戏。

19.1 创建项目、添加资源

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

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 配置关卡数据

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


19.21 根据数据创建金币银币

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

19.22 金币翻转特效

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

19.23 提升用户体验

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




19.24 周围金币翻转

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





19.25 判断胜利

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




19.26 胜利图片显示

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


19.27 添加开始按钮音效

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



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

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

19.29 项目打包

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


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


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

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

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

Qt从安装到实战项目相关推荐

  1. 【北京迅为】嵌入式Linux+QT开发零基础入门+项目实战教程分享

    B站搜'北京迅为', 入门视频教程免费学习,持续更新. https://space.bilibili.com/33785640 0基础学习+知识点 +实战项目演练 视频精简,思路清晰,不做无用功,让所 ...

  2. QT 基础知识一(QT安装、创建项目、常用窗口控件使用、信号与槽机制讲解)

    QT概念 Qt:Qt是一个跨平台的C++框架(C++库),Qt除了支持界面设计(GUI编程),还封装了与网络编程.多线程.数据库连接.视频音频等相关的功能. ctrl 撤销(返回上一步) 市面常见的G ...

  3. TensorFlow 中文资源精选,官方网站,安装教程,入门教程,实战项目,学习路径。

    转载至:http://www.nanjixiong.com/thread-122211-1-1.html Awesome-TensorFlow-Chinese TensorFlow 中文资源全集,学习 ...

  4. Qt实战项目:高精度表达式计算器Qt

    高精度表达式计算器Qt 表达式计算器是一个由C++ with QT编写的应用程序.这个计算器旨在通过引入表达式计算的概念解决Windows默认计算器显示不直观的问题,提供了普通型计算器.科学型计算器的 ...

  5. 迅为-i.MX6ULL开发板-QT实战项目DHT11网络编程实战练习(一)

    迅为-i.MX6ULL开发板-QT实战项目DHT11&网络编程实战练习(一) 发布时间:2021-7-2 09:49    发布者:落风 |编辑 文章目录1 项目前准备2 软件流程图3 Lin ...

  6. Qt | UDP广播通信的使用、实战项目使用案例

    Qt | UDP广播通信的使用.实战项目使用案例 1.UDP广播介绍 UDP广播地址固定IP地址为:XXX.XXX.XXX.255. 如果向全网段发送广播消息,那么广播地址为:255.255.255. ...

  7. docker 安装nacos_19.SpringCloud实战项目-SpringCloud整合Alibaba-Nacos配置中心

    SpringCloud实战项目全套学习教程连载中 PassJava 学习教程 简介 PassJava-Learning项目是PassJava(佳必过)项目的学习教程.对架构.业务.技术要点进行讲解. ...

  8. python有趣的小项目-有趣的十个Python实战项目,让你瞬间爱上Python!

    前言 Python 是一种极具可读性和通用性的编程语言.Python 这个名字的灵感来自于英国喜剧团体 Monty Python,它的开发团队有一个重要的基础目标,就是使语言使用起来很有趣.Pytho ...

  9. python项目开发实例-有趣的十个Python实战项目,让你瞬间爱上Python!

    前言 Python 是一种极具可读性和通用性的编程语言.Python 这个名字的灵感来自于英国喜剧团体 Monty Python,它的开发团队有一个重要的基础目标,就是使语言使用起来很有趣.Pytho ...

最新文章

  1. 2022-2028年中国TCO导电玻璃行业市场研究分析及前瞻规划报告
  2. HTML引用公共组件
  3. 3名程序员被抓!开发“万能钥匙”APP,撬走3个亿
  4. HttpClient post 与get
  5. vivado调用modelsim
  6. xp 安装mysql数据库_Windows XP系统中安装MySQL5.5.28数据库图文教程
  7. php think命令用不了,自定义 PHP think 命令无法在命令类文件里面使用 Db 类
  8. PHP如何验证以太坊签名
  9. 计算机软硬件基础体系标准,国内首个计算机软硬件基础体系标准发布
  10. svn教程----示例二:测试人员拥有读权限
  11. python干啥用_用python内置函数能干些什么?
  12. VSCode同步设置
  13. 修复win10的更新服务器,大师搞定win10系统自动更新失败的修复步骤
  14. MFCC梅尔频率倒谱系数
  15. C++ const修饰指针变量的位置不同代表的意义
  16. 小知识--DOS命令2
  17. win10系统服务器不能创建对象,win10系统中activex部件不能创建对象怎么修复
  18. audio realtek 耳机没声_解决Realtek High Definition Audio 声卡前面板耳机无声音方法
  19. vim插入模式快捷键
  20. 从头学习爬虫(十六)进阶篇----第三方接口

热门文章

  1. 统计学生平均成绩。使用静态成员函数。如果不将average函数定义为静态成员函数行不行?程序能否通过编译?需要作什么修改?为什么要用静态成员函数?请分析其理由。
  2. Linux-saltstack-4 jinjia模板得基本使用
  3. 不切入CAN总线的车联网都是伪车联网--转载至虎嗅网
  4. 电脑剪切,CopyQ(电脑剪切板) V4.1.0 最新版
  5. 在windows2000中提示您无法关闭计算机!
  6. 用C语言实现飞机大战小游戏
  7. 计算机毕业设计django基于python的宠物分享网站
  8. 3d离线地图,如何实现?
  9. lotus-miner扇区销毁、提币
  10. Android应用开发-小巫CSDN博客客户端UI篇,成功从小公司跳槽