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 和 最基本的框架,先實現核心功能:
● 先實現以下部分:
可以參考第一個版本的代碼 v0.1:
1. 后端數據處理
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() { }//返回下一組算術 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 <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. 導出 C++ 對象的 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(); }主要在默認的 main.cpp 中增加上述 [flag] 三處
3. 前臺 UI 數據
import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.5Window {visible: truewidth: 640height: 480title: qsTr("瘋狂算術")color: "#84C1FF"Button {id: startBtnanchors.centerIn: parenttext: "開始"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"}}} }三、完善執行邏輯(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 本地化(翻譯)
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
翻譯后發布:
方法二,執行指令:
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<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 中調用
//main.qmlimport cc.Values 1.0Values {id: values }function gameOver() {values.bestScore = Math.max(values.bestScore, currentScore)... }GitHub 地址: ????QmlLearningPro ,選擇子工程 CrazyMath.pro
QML 其它文章請點擊這里: ????QT QUICK QML 學習筆記
總結
以上是生活随笔為你收集整理的Qt Quick QML 实例之疯狂数字游戏(QML C++混合编程、翻译、QSetting )【建议收藏】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汇编语言--8254定时/计数器实验
- 下一篇: 用VC++6.0的MFC框架编写的采集N