QT|Qt Quick QML 实例之疯狂数字游戏(QML C++混合编程、翻译、QSetting )【建议收藏】
文章目录
- 一、开门见山
- 二、最基本的框架(v0.1)
-
- 1. 后端数据处理
- 2. 导出 C++ 对象的 QML 的属性
- 3. 前台 UI 数据
- 三、完善执行逻辑(v0.2)
- 四、发布版本(v1.0)
-
- 1. 翻译
- 2. QSetting 数据保存
GitHub 源码:QmlLearningPro ,选择子工程 CrazyMath.pro
QML 其它文章请点击这里:QT QUICK QML 学习笔记
一、开门见山 ● Windows 下运行效果:
● Android 下运行效果:
此实例,参考了安老师 的 Qt Quick实现的疯狂算数游戏,在此基础上一步步深入学习和完善,非常适合 Qt QML 和 C++ 学习入门。
● 可供学习的点:
1)跨平台程序,Windows 和 Android 下都能运行;2)C++ 与QML 相结合,在 QML 文件中使用了两种方法调用 C++ 类;3)自定义不同的基础控件,如悬浮按钮CCHoverHorzButton、文本CCLabel,方便移植;4)QML 中不同控件的使用,column、SpringAnimation、transitions、State 等等;5)数据可持久化,利用 QSettings 可以把内存中的数据保存到地电脑的磁盘中;6)加入国际化翻译机制
二、最基本的框架(v0.1) 最简单的 UI 和 最基本的框架,先实现核心功能:
文章图片
● 先实现以下部分:
1)基本的框架2)增加**开始键**,开始游戏3)增加**确认(√)按键**,确定下一组的算术题目
可以参考第一个版本的代码 v0.1:
文章图片
1. 后端数据处理 MathProblem.cpp
#include "MathProblem.h"const char *MathProblem::_problems[] = {
"1 + 2 = ", "2 + 3 = ", "2 + 2 = ","1 + 4 = ", "2 + 5 = " };
const intMathProblem::_answers[]= {
3,5,4,5,7 };
MathProblem::MathProblem(QObject *parent)
: QObject(parent)
, newIdx(0)
{}MathProblem::~MathProblem() {}//返回下一组算术
QString MathProblem::nextMath()
{newIdx = qrand() % 5;
//随机的答案
int randAnswer = _answers[newIdx] + (qrand() % 7 - 3);
// 取 -3~3 的随机数
return QString("%1%2").arg(_problems[newIdx]).arg(randAnswer);
}
MathProblem.h
#ifndef MATH_PROBLEM_H
#define MATH_PROBLEM_H#include
#include //using namespace::std;
class MathProblem : public QObject {Q_OBJECT
public:
MathProblem(QObject *parent = nullptr);
~MathProblem();
Q_INVOKABLE QString nextMath();
//Q_INVOKABLE
private:
int newIdx;
static const char * _problems[];
static const int_answers[];
};
#endif
2. 导出 C++ 对象的 QML 的属性
#include
#include
#include "MathProblem.h"//[flag1]
#include //[flag2]int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
//C++ && QML programminghttps://blog.csdn.net/qq_16504163/article/details/105189471
engine.rootContext()->setContextProperty("MathProblem", new MathProblem);
//[flag3]
engine.load(url);
return app.exec();
}
主要在默认的 main.cpp 中增加上述 [flag] 三处
3. 前台 UI 数据
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5Window {visible: true
width: 640
height: 480
title: qsTr("疯狂算术")
color:"#84C1FF"Button {id:startBtn
anchors.centerIn:parent
text:"开始"
onClicked:{startBtn.visible = false
columnRoot.visible = true
mathText.text = MathProblem.nextMath();
}
}
Column {id:columnRoot
visible:false
anchors.top:parent.top
anchors.topMargin:parent.width*0.1
anchors.horizontalCenter:parent.horizontalCenter
spacing:20
Text {id:mathText;
color:"white"
font.pointSize:28
font.bold:true
anchors.horizontalCenter: parent.horizontalCenter
}
Row {spacing:10
anchors.horizontalCenter: parent.horizontalCenter
Button {text: "√"
onClicked:
mathText.text = MathProblem.nextMath();
}
Button {text: "X"
}
}
}
}
三、完善执行逻辑(v0.2) 第二个版本,演示如下:
文章图片
● 增加功能:
1)增加游戏结束界面2)判断回答是否正确,回答正确进入下一题,回答错误进入结束界面3)增加到60个算术题4)增加计时功能,设定为 4s,超时则进入结束界面5)增加积分:答对1题 +10,再加上 剩余的时间 *5,如剩余的时候为 2s 时候,积分:10 + 2 * 5 = 20
● 主要 UI 代码结构如下:
main.qml :
文章图片
可以下载源码,参考第二个版本 v0.2, C++ 后台数据中基本不变
四、发布版本(v1.0) ● 增加功能:
1)美化界面2)整理结构3)跨平台程序,**Windows** 和 **Android** 下都能运行;4)C++ 与QML 相结合,在 QML 文件中使用了两种方法调用 C++ 类;5)自定义不同的基础控件,如悬浮按钮CCHoverHorzButton、文本CCLabel,方便移植;6)数据可持久化,利用 QSettings 可以把内存中的数据保存到地电脑的磁盘中;7)加入国际化翻译机制;
● 目录结构:
文章图片
源码更新了很多,包括执行的逻辑,具体看源码,再这里展开说下 国际化翻译机制 和QSettings 数据可持久化
1. 翻译 【QT|Qt Quick QML 实例之疯狂数字游戏(QML C++混合编程、翻译、QSetting )【建议收藏】】
文章图片
参考:Qt 本地化(翻译)
1)准备要翻译的源代码
在 QML 中使用 qsTr() 来包裹,在 cpp 中使用 tr() 来包裹。用它包裹的文本会被 Qt Linguist(Qt 语言家)捕捉到从而进行翻译工作。
//main.qml
text:qsTr("Correct")
2)生成 xxx.ts 文件
先在 CrazyMath.pro 文件中添加如下代码:
TRANSLATIONS += $$PWD/Translations/zh_CN.ts
可以使用两种方法生成:
① 在 Qt Creator 的菜单栏中依次点击 工具->外部->Qt语言家->发布更新翻译(lrelease)(lupdate),就会在源代码文件所在的目录生成 ts 文件。
文章图片
② 使用 CMD 命令生成:
文章图片
使用 lupdate CrazyMath.pro
文章图片
3)翻译并生成 qm 文件
方法一: 右键打开翻译文件 zh_CN.ts
文章图片
翻译后发布:
文章图片
方法二,执行指令:
lrelease -verbose zh_CN.ts
文章图片
4)加载 qm 翻译文件
在 main.cpp 中加载生成的 qm 文件
void setLanguage(QGuiApplication *app) {QLocale locale = QLocale::system();
if(locale.language() == QLocale::Chinese)
{QTranslator *translator = new QTranslator(app);
///--以下三种方法都可以加载翻译文件
if(translator->load(":/translations/zh_CN.qm"))
//if(translator->load(locale, ":/translations/zh_CN.qm", "", ":/i18n"))
//if (translator->load(locale, "zh_CN", ".", ":/translations", ".qm"))
{app->installTranslator(translator);
}
else {qDebug() << "Error loading source localization ";
}
}
}
最后编译即可。
2. QSetting 数据保存 纯 QML 软件状态的保存可以参考这个:QT Quick QML 之Setting状态保存
本文设定了 bestScore 变量来保存历史最好成绩 ,在软件关闭后能保存到注册表中。
文章图片
如果指定了名字,公司等,就不需要手动创建.ini配置文件了, 会自动创建ini文件,且保存到注册表中:
main.cpp:
void setOrganization(void) {QCoreApplication::setOrganizationName("CrazyMath");
QCoreApplication::setOrganizationDomain("CrazyMath.com");
QCoreApplication::setApplicationName("CrazyMath");
}//注册:
qmlRegisterType("cc.Values",1, 0, "Values");
cpp 源文件:
//Values.cc
#include "Values.h"
#include
#include const char* Values::_groupKey ="values";
const char* Values::_bestScoreKey ="bestScore";
Values::Values(void)
{QSettings settings;
settings.beginGroup(_groupKey);
//获取初值
_bestScore = settings.value(_bestScoreKey).toInt();
//更新 qml 值
emit bestScoreChanged(_bestScore);
qDebug() <<"Setting fileName is :" <.fileName();
qDebug() <<"_bestScore is :" << _bestScore;
}void Values::setBestScore(const int& bestScore)
{QSettings settings;
settings.beginGroup(_groupKey);
settings.setValue(_bestScoreKey, bestScore);
_bestScore = bestScore;
emit bestScoreChanged(_bestScore);
qDebug() <<"_bestScore is :" << _bestScore;
}
打印的路径:
文章图片
.h 头文件:
//Values.h:
#ifndef Values_H
#define Values_H#include class Values : public QObject
{Q_OBJECT
public:
Values(void);
Q_PROPERTY(int bestScore READ bestScore WRITE setBestScore NOTIFY bestScoreChanged)
int bestScore(void) const {
return _bestScore;
}
void setBestScore(const int& bestScore);
signals:
void bestScoreChanged(int bestScore);
private:
int _bestScore;
static const char* _groupKey;
static const char* _bestScoreKey;
};
#endif
QML 中调用
//main.qmlimport cc.Values1.0Values {id: values
}function gameOver() {values.bestScore = Math.max(values.bestScore, currentScore)
...
}
GitHub 地址:QmlLearningPro ,选择子工程 CrazyMath.pro
QML 其它文章请点击这里:QT QUICK QML 学习笔记
推荐阅读
- LSTM网络层详解及其应用实例
- Python-类和对象
- SpringBoot整合MongoDB完整实例代码
- MySQL|MySQL 存储过程语法及实例
- thinkphp3.2下实现阿里云视频点播实例(客户端JavaScript上传)
- Servlet原理|Servlet原理 二(Web应用与创建Servlet实例)
- (4)Canal多实例使用
- QML基础信息
- C# 接口实例
- locust实例