背景:
【qml-1】qml與c++交互第一次嘗試(實例注入)
【qml-2】嘗試一個有模式的qml彈窗
【qml-3】qml與c++交互第二次嘗試(類型注冊)
【qml-4】qml與c++交互(類型多例)
【qml-5】qml與c++交互(類型單例)
此篇接著上篇的話題,“類型多例”這個是我造的詞,這種方式使用簡單,如果咱們是熟悉qt的程序員,c++部分不需要特別注意,只要Q_INVOKABLE、槽、信號就行,亦即qml的工作原理。但之前提到,“類型多例”會在qml中實例化多次,所以就有了本次單例的做法。
類型定義:
相當于做個單例模式,但不太一樣。
//-----------cppbase.h--------------#ifndef CPPBASE_H
#define CPPBASE_H#include <QObject>
#include <QQmlEngine>class CppBase : public QObject
{Q_OBJECTQML_ELEMENT
public:explicit CppBase(QObject *parent = nullptr);static CppBase* instance();//這里Q_INVOKABLE QString f_INI_GetUserInfo();
};#endif // CPPBASE_H//-----------cppbase.cpp--------------#include "cppbase.h"Q_GLOBAL_STATIC(CppBase, globalCppBase)//這里CppBase* CppBase::instance() //這里
{return globalCppBase();
}CppBase::CppBase(QObject *parent): QObject{parent}
{}QString CppBase::f_INI_GetUserInfo()
{ ... }
上面需要注意不一樣的地方我加了注釋。這里不討論線程安全或者單例模式本身的話題,只說qml應用。
用它這個宏,如果不換行會有錯誤提示,換行了也有別的錯誤提示,還要求構造公有。如果不用這個宏,可以寫個傳統單例一樣用。
單例注冊:
qmlRegisterSingletonInstance("CppBase", 1, 0, "CppBase", CppBase::instance());
還是倆字符串參數,第一個用于import,第二個用于qml中類型引用。這里注冊的是單例。
qml調用:
import CppBaseItem {function f() {let sJsonStr = CppBase.f_INI_GetUserInfo();}
}
行了。
總結:
方法也越來越簡練了。還是三步:定義、注冊、使用。
關于自動補全,其實從第一種“實例方式”開始,qml都可以提示自動補全的,就是“實例注入”方式可能要運行一下才能提示,這個自從用了cmake以后,我覺得跟build目錄里生成的一堆有關系。這里不深究了。
其它幾種調用c++的方式都很方便,在qml中都有補全提示和高亮顯示。
如果需要成員的補全提示,比如打個點能提示函數名,就需要向qml注冊類型,而不是只注冊單例,就像c++里只引用可以前置聲明,想用里面東西還得包含頭文件,一個道理。如下:
qmlRegisterType<CppBase> ("CppBase", 1, 0, "CppBase");
我是為了方便注冊類型了。
creator還可以給js打斷點調試,非常方便。
本文完。