背景:
【qml-1】qml與c++交互第一次嘗試(實例注入)
【qml-2】嘗試一個有模式的qml彈窗
【qml-3】qml與c++交互第二次嘗試(類型注冊)
【qml-4】qml與c++交互(類型多例)
【qml-5】qml與c++交互(類型單例)
之前提到的“實例注入”方式,是在c++中實例化再注入qml,手冊中是不推薦這么做的。問AI答案是:
????????為什么避免context properties:
????????破壞組件封裝性
????????使數據流難以追蹤
????????導致組件難以單獨測試
????????可能產生循環依賴
我認為有興趣可以研究。
而之前提到的類型方式,用起來也不是我想要的“簡潔”效果,實際項目中我用了一種自認為比較方便的用法,記錄下來。
qml項目建議:
之前提到過qml分離方式我試出來并不好,于是使用qrc方式。我是從Design Studio里做好界面導出qrc,然后把qml目錄和qrc復制到c++項目中使用的。
實際DS應該可以生成cmake,可以直接用creator原地打開項目,但它生成的東西太多,我就沒有采用這種方式。
類型定義:
寫個c++類,供qml使用。
//-----------------------cppdb.h------------------------------#ifndef CPPDB_H
#define CPPDB_H#include <QObject>
#include <QQmlEngine>class CppDB : public QObject
{Q_OBJECTQML_ELEMENT
public:explicit CppDB(QObject *parent = nullptr);public://LogsQ_INVOKABLE void f_Logs_Write(QString sLogText);
};#endif // CPPDB_H//-----------------------cppdb.cpp--------------------------#include "cppdb.h"CppDB::CppDB(QObject *parent): QObject{parent}
{}
/*** Write the logs to db.*/
void CppDB::f_Logs_Write(QString sLogText)
{...
}
類型注冊:
程序加載時調用即可,比如main函數中,應該放在qml load之前。我習慣是用另一個靜態類寫成靜態函數,main函數中調用一行即可。以后方便維護。
qmlRegisterType<CppDB>("CppDB", 1, 0, "CppDB");
其中,第一個字符串用于qml中的import,第二個字符串用于qml中的類型引用(類似Button和Text)。然后就沒有然后了,簡單吧。
qml調用:
接著在qml中這樣用:
import CppDBItem {CppDB { id: _cppDB }function f() {_cppDB.f_Logs_Write(qsTr("這條寫入日志。舉個例子而已。"));}
}
總結:
上面就三步,不需要改qmakelists.txt,不需要涉及路徑,我認為已經非常簡練。
但要明白,這種用法跟自己寫了個qml的Button一樣,它就是個類型,qml中使用{}實例化它。亦即,如果這個類型在多個qml中使用,那就實例化了多份,所以本篇的題目注釋叫(類型多例方式)。
因此,這種方法利弊共存,看你怎么想了。我是個人認為,除了浪費內存,沒啥不好,簡潔好維護。
所以就有了后面的“類型單例”方式。
本文完。