背景:
【qml-5】qml與c++交互(類型單例)
之前記錄過qml與c++交互的方式,目前為止我使用的是“類型單例”方式。這些名字是我自己起的,只為說明問題,嚴謹的還是以手冊為準。
“類型單例”方式時提到過自動補全提示問題,就如前置聲明和頭文件一樣,需要注冊類型,所以以前我是這樣做的:
qmlRegisterType<CppGrid>("CppGrid", 1, 0, "CppGrid");qmlRegisterSingletonInstance("CppGrid", 1, 0, "CppGrid", CppGrid::instance());
最早的時候我每寫一個類,都會給它注冊一個單獨的uri,用于qml的import。后來發現有時候即使注冊了類型也不能補全提示。
我的初衷是,要心情愉悅地寫qml,就一定要解決自動補全提示的問題,每次在類型名后面打點必須給出提示。網上搜了一堆,一個比一個麻煩,我就是要簡潔,不修改cmake,不用qmldir和目錄,除了簡單加極少代碼其它一概不用,只改涉及一處,好維護好理解。
所以開始研究。
URI:
這個用于qml import的uri,后來我想干脆都用一個算了,因為目前的項目規模有限,分太細沒必要,書寫繁瑣,所以后來都用“Cpp”取代了。
注冊函數:
以前像上面那樣使用注冊函數,初衷就是為了簡潔好管理。
但終歸發現注冊類型和單例同時存在會有問題,因為使用了同一個模塊(uri),又用同一個類型名,它就有可能不穩定。總之就是不建議一起用。
所以查詢了AI和手冊,最終確定了更簡潔的用法:
qmlRegisterSingletonType<CppGrid>("CppSingleton", 1, 0, "CppGrid",[](QQmlEngine*, QJSEngine*) { return CppGrid::instance(); });
凡是需要單例注冊的,就這樣一行即可。導入時只需要import CppSingleton,再使用CppGrid打點時,一定會出現補全提示。
項目中我還做了一個分頁組件,需要qml和c++協作,所以它專屬的CppPage類型,我沒有使用單例,而是類型注冊,因為需要每個調用它的ui有獨立的信號槽,就必須每個ui實例化。所以目前只有這個是使用類型注冊的。
qmlRegisterType<CppPage>("CppType", 1, 0, "CppPage");
uri就用“CppType”吧,以后有其它需要類型注冊的,也用這個名字,不分太細了,累。
總結:
本次記錄的目的,就是因為曾遇到了補全提示不正常的情況,一定要搞定它,寫qml才舒服。
本文完。