Qt Quick QML 实例之疯狂数字游戏(QML C++混合编程、翻译、QSetting )【建议收藏】
文章目錄
- 一、開(kāi)門見(jiàn)山
- 二、最基本的框架(v0.1)
- 1. 后端數(shù)據(jù)處理
- 2. 導(dǎo)出 C++ 對(duì)象的 QML 的屬性
- 3. 前臺(tái) UI 數(shù)據(jù)
- 三、完善執(zhí)行邏輯(v0.2)
- 四、發(fā)布版本(v1.0)
- 1. 翻譯
- 2. QSetting 數(shù)據(jù)保存
GitHub 源碼: ????QmlLearningPro ,選擇子工程 CrazyMath.pro
QML 其它文章請(qǐng)點(diǎn)擊這里: ????QT QUICK QML 學(xué)習(xí)筆記
一、開(kāi)門見(jiàn)山
● Windows 下運(yùn)行效果:
● Android 下運(yùn)行效果:
此實(shí)例,參考了安老師 的 Qt Quick實(shí)現(xiàn)的瘋狂算數(shù)游戲,在此基礎(chǔ)上一步步深入學(xué)習(xí)和完善,非常適合 Qt QML 和 C++ 學(xué)習(xí)入門。
● 可供學(xué)習(xí)的點(diǎn):
1)跨平臺(tái)程序,Windows 和 Android 下都能運(yùn)行;2)C++ 與 QML 相結(jié)合,在 QML 文件中使用了兩種方法調(diào)用 C++ 類;3)自定義不同的基礎(chǔ)控件,如懸浮按鈕CCHoverHorzButton、文本CCLabel,方便移植;4)QML 中不同控件的使用,column、SpringAnimation、transitions、State 等等;5)數(shù)據(jù)可持久化,利用 QSettings 可以把內(nèi)存中的數(shù)據(jù)保存到地電腦的磁盤中;6)加入國(guó)際化翻譯機(jī)制二、最基本的框架(v0.1)
最簡(jiǎn)單的 UI 和 最基本的框架,先實(shí)現(xiàn)核心功能:
● 先實(shí)現(xiàn)以下部分:
可以參考第一個(gè)版本的代碼 v0.1:
1. 后端數(shù)據(jù)處理
MathProblem.cpp
#include "MathProblem.h"const char *MathProblem::_problems[] = { "1 + 2 = ", "2 + 3 = ", "2 + 2 = ","1 + 4 = ", "2 + 5 = " }; const int MathProblem::_answers[] = { 3, 5, 4, 5, 7 };MathProblem::MathProblem(QObject *parent): QObject(parent), newIdx(0) { }MathProblem::~MathProblem() { }//返回下一組算術(shù) QString MathProblem::nextMath() {newIdx = qrand() % 5;//隨機(jī)的答案int randAnswer = _answers[newIdx] + (qrand() % 7 - 3); // 取 -3~3 的隨機(jī)數(shù)return QString("%1%2").arg(_problems[newIdx]).arg(randAnswer); }MathProblem.h
#ifndef MATH_PROBLEM_H #define MATH_PROBLEM_H#include <QObject> #include <QString>//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[]; };#endif2. 導(dǎo)出 C++ 對(duì)象的 QML 的屬性
#include <QGuiApplication> #include <QQmlApplicationEngine> #include "MathProblem.h" //[flag1] #include <QQmlContext> //[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 programming https://blog.csdn.net/qq_16504163/article/details/105189471engine.rootContext()->setContextProperty("MathProblem", new MathProblem); //[flag3]engine.load(url);return app.exec(); }主要在默認(rèn)的 main.cpp 中增加上述 [flag] 三處
3. 前臺(tái) UI 數(shù)據(jù)
import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.5Window {visible: truewidth: 640height: 480title: qsTr("瘋狂算術(shù)")color: "#84C1FF"Button {id: startBtnanchors.centerIn: parenttext: "開(kāi)始"onClicked: {startBtn.visible = falsecolumnRoot.visible = truemathText.text = MathProblem.nextMath();}}Column {id: columnRootvisible: falseanchors.top: parent.topanchors.topMargin: parent.width*0.1anchors.horizontalCenter: parent.horizontalCenterspacing: 20Text {id: mathText;color: "white"font.pointSize: 28font.bold: true anchors.horizontalCenter: parent.horizontalCenter}Row {spacing: 10anchors.horizontalCenter: parent.horizontalCenterButton {text: "√"onClicked:mathText.text = MathProblem.nextMath();}Button {text: "X"}}} }三、完善執(zhí)行邏輯(v0.2)
第二個(gè)版本,演示如下:
● 增加功能:
1)增加游戲結(jié)束界面2)判斷回答是否正確,回答正確進(jìn)入下一題,回答錯(cuò)誤進(jìn)入結(jié)束界面3)增加到60個(gè)算術(shù)題4)增加計(jì)時(shí)功能,設(shè)定為 4s,超時(shí)則進(jìn)入結(jié)束界面5)增加積分:答對(duì)1題 +10,再加上 剩余的時(shí)間 *5,如剩余的時(shí)候?yàn)?2s 時(shí)候,積分:10 + 2 * 5 = 20● 主要 UI 代碼結(jié)構(gòu)如下:
main.qml :
可以下載源碼,參考第二個(gè)版本 v0.2, C++ 后臺(tái)數(shù)據(jù)中基本不變
四、發(fā)布版本(v1.0)
● 增加功能:
1)美化界面2)整理結(jié)構(gòu)3)跨平臺(tái)程序,**Windows** 和 **Android** 下都能運(yùn)行;4)C++ 與 QML 相結(jié)合,在 QML 文件中使用了兩種方法調(diào)用 C++ 類;5)自定義不同的基礎(chǔ)控件,如懸浮按鈕CCHoverHorzButton、文本CCLabel,方便移植;6)數(shù)據(jù)可持久化,利用 QSettings 可以把內(nèi)存中的數(shù)據(jù)保存到地電腦的磁盤中;7)加入國(guó)際化翻譯機(jī)制;● 目錄結(jié)構(gòu):
源碼更新了很多,包括執(zhí)行的邏輯,具體看源碼,再這里展開(kāi)說(shuō)下 國(guó)際化翻譯機(jī)制 和QSettings 數(shù)據(jù)可持久化
1. 翻譯
參考:Qt 本地化(翻譯)
1)準(zhǔn)備要翻譯的源代碼
在 QML 中使用 qsTr() 來(lái)包裹,在 cpp 中使用 tr() 來(lái)包裹。用它包裹的文本會(huì)被 Qt Linguist(Qt 語(yǔ)言家)捕捉到從而進(jìn)行翻譯工作。
//main.qml text: qsTr("Correct")2)生成 xxx.ts 文件
先在 CrazyMath.pro 文件中添加如下代碼:
TRANSLATIONS += $$PWD/Translations/zh_CN.ts可以使用兩種方法生成:
① 在 Qt Creator 的菜單欄中依次點(diǎn)擊 工具->外部->Qt語(yǔ)言家->發(fā)布更新翻譯(lrelease)(lupdate),就會(huì)在源代碼文件所在的目錄生成 ts 文件。
② 使用 CMD 命令生成:
使用 lupdate CrazyMath.pro
3)翻譯并生成 qm 文件
方法一: 右鍵打開(kāi)翻譯文件 zh_CN.ts
翻譯后發(fā)布:
方法二,執(zhí)行指令:
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 數(shù)據(jù)保存
純 QML 軟件狀態(tài)的保存可以參考這個(gè):QT Quick QML 之Setting狀態(tài)保存
本文設(shè)定了 bestScore 變量來(lái)保存歷史最好成績(jī) ,在軟件關(guān)閉后能保存到注冊(cè)表中。
如果指定了名字,公司等,就不需要手動(dòng)創(chuàng)建.ini配置文件了, 會(huì)自動(dòng)創(chuàng)建ini文件,且保存到注冊(cè)表中:
main.cpp:
void setOrganization(void) {QCoreApplication::setOrganizationName("CrazyMath");QCoreApplication::setOrganizationDomain("CrazyMath.com");QCoreApplication::setApplicationName("CrazyMath"); }//注冊(cè): qmlRegisterType<Values> ("cc.Values", 1, 0, "Values");cpp 源文件:
//Values.cc #include "Values.h" #include <QSettings> #include <qdebug.h>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 :" <<settings.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 <QObject>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; };#endifQML 中調(diào)用
//main.qmlimport cc.Values 1.0Values {id: values }function gameOver() {values.bestScore = Math.max(values.bestScore, currentScore)... }GitHub 地址: ????QmlLearningPro ,選擇子工程 CrazyMath.pro
QML 其它文章請(qǐng)點(diǎn)擊這里: ????QT QUICK QML 學(xué)習(xí)筆記
總結(jié)
以上是生活随笔為你收集整理的Qt Quick QML 实例之疯狂数字游戏(QML C++混合编程、翻译、QSetting )【建议收藏】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 汇编语言--8254定时/计数器实验
- 下一篇: php 7天余额显示不出来的,为何我在余