日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt 从C ++定义QML类型(二)

發布時間:2025/1/21 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt 从C ++定义QML类型(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

在上一篇文章中介紹了如何注冊一個C++的可實例化的對象類型供 QML 中使用,那么今天繼續之前的文章介紹。

正文

注冊不可實例化類型

有時候QObject派生類可能需要在QML類型系統中注冊,但不能作為可實例化類型。例如,如果C ++類是這種情況:

1.是一個不應該實例化的接口類型
2.是不需要暴露給QML的基類類型
3.聲明了一些應該可以從QML訪問的枚舉,但除此之外不應該是可實例化的
4.通過單例實例提供給QML的類型,不應該從QML實例化

在Qt的QML模塊提供用于登記非實例類型的幾種方法:

  • qmlRegisterType()(不帶參數)注冊一個C ++類型,該類型不可實例化,不能從QML引用。這使得引擎可以強制從QML實例化的任何繼承類型。
  • qmlRegisterInterface()注冊具有特定QML類型名稱的Qt接口類型。該類型不是從QML實例化的,但可以通過其類型名稱引用。
  • qmlRegisterUncreatableType()注冊一個不可實例化的命名C ++類型,但可以識別為QML類型系統的一個類型。如果類型的枚舉或附加屬性可以從QML訪問,但是類型本身不應該是可實例化的,那么這個方法可以用到。
  • qmlRegisterSingletonType()注冊一個可以從QML導入的單例類型。

注意,使用QML類型系統注冊的所有C ++類型都必須是QObject派生的,即使是不可實例化類。

用單例類型注冊單例對象

單例類型讓屬性、信號和方法能夠暴露在名稱空間中,而不需要客戶端手動實例化對象實例。特別是QObject單例類型是提供功能或全局屬性值的一種高效方便的方法。

請注意,單例類型沒有關聯的QQmlContext,因為它們在引擎中的所有上下文之間共享。QObject單例類型實例由QQmlEngine構建并擁有,并且在引擎銷毀時將被銷毀。

一個QObject單例類型可以以類似于任何其他QObject或實例化類型的方式進行交互,除了只存在一個(引擎構造和擁有的)實例,并且它必須通過類型名稱而不是id引用。可以綁定QObject單例類型的Q_PROPERTY ,并且可以在信號處理程序表達式中使用QObject模塊API的Q_INVOKABLE函數。這使得singleton類型成為實現樣式或主題的理想方式,并且它們也可以用來代替存儲全局狀態或提供全局功能。

一旦注冊,一個QObject單例類型可以被導入和使用,就像任何其他暴露給QML的QObject實例一樣。
如下示例:
假如這里的Theme已經注冊到MyThemeModule 1.0系統空間。并且定義了 color 屬性,那么在 QML 中可以直接進行引用。

import MyThemeModule 1.0 as Theme Rectangle {color: Theme.color // binding. }

注意: QML中注冊類型的枚舉值應該以大寫字母開頭。

OK,接下來我們看看qmlRegisterSingletonType 注冊一個可以從 QML 導入的單例對象。

qmlRegisterSingletonType函數說明

qmlRegisterSingletonType一共有三個重構函數,先來看看函數的聲明。

int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QJSValue(* ) ( QQmlEngine *, QJSEngine * ) callback) int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *(* ) ( QQmlEngine *, QJSEngine * ) callback) int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
1.int qmlRegisterSingletonType(const char uri, int versionMajor, int versionMinor, const char *typeName, QJSValue( ) ( QQmlEngine , QJSEngine ) callback)

此函數可用于在特定的uri和typeName中注冊singleton類型提供者回調,其版本在versionMajor和versionMinor中指定。
單例類型可以是QObject或QJSValue。這個函數應該用來注冊一個單例類型的提供者函數,它返回一個QJSValue作為單例類型。

注: 如果更改,QJSValue單例類型屬性不會觸發綁定。

來看看示例:

//首先,定義單例類型提供者回調函數 static QJSValue example_qjsvalue_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine) {Q_UNUSED(engine)static int seedValue = 5;QJSValue example = scriptEngine->newObject();example.setProperty("someProperty", seedValue++);qDebug() << __FUNCTION__ << seedValue;return example; }int main(int argc, char *argv[]) {QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;//第二,通過在初始化函數中調用該函數,用QML注冊單例類型提供程序qmlRegisterSingletonType("Qt.example.qjsvalueApi", 1, 0, "MyApi", example_qjsvalue_singletontype_provider);engine.load(QUrl(QLatin1String("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec(); }

這里在注冊的時候也可以寫成 Lambda 函數:如下:

qmlRegisterSingletonType("Qt.example.qjsvalueApi", 1, 0, "MyApi", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QJSValue {Q_UNUSED(engine)static int seedValue = 5;QJSValue example = scriptEngine->newObject();example.setProperty("someProperty", seedValue++);return example; });

在 QML 中調用:

import QtQuick 2.0 import Qt.example.qjsvalueApi 1.0 as ExampleApi Item {id: rootproperty int someValue: ExampleApi.MyApi.somePropertyComponent.onCompleted: {console.log("someValue = ",someValue)} }

程序輸出:

example_qjsvalue_singletontype_provider 6 qml: someValue = 5

注意,這里的someValue再次調用還是保持之前的值,也就是說不會重復進入到回調函數中。經過多次測試均是如此。

個人覺得上面這種用法在實際的場景中應該使用得不多,那么接下來看看第二個。

2.int qmlRegisterSingletonType(const char uri, int versionMajor, int versionMinor, const char *typeName, QObject (* ) ( QQmlEngine , QJSEngine ) callback)

和上面那個注冊函數不同的是,這里是返回一個 QObject 對象類型的回調。

一個QObject單例類型可以通過它所注冊的類型名稱被引用,并且這個類型名稱可以用作Connections類型中的目標,或者用作任何其他類型的id。一個例外是QObject單例類型屬性不能被別名(因為單例類型名稱不能識別與其他任何項目相同的組件中的對象)。

注:一個QObject的從單類型提供者返回單類型實例是由QML引擎所有,除非對象有明確的QQmlEngine :: CppOwnership標志設置。

來看看示例:

//定義一個繼承于 QObject 的功能類class Student : public QObject {Q_OBJECTQ_PROPERTY(QString name READ getName WRITE setName NOTIFY sigNameChanged)public:explicit Student(QObject *parent = nullptr):QObject(parent){}~Student(){}void setName(const QString & name){if(name != m_name){m_name = name;emit sigNameChanged(m_name);}}QString getName() const {return m_name;}Q_INVOKABLE QString doSomething(){qDebug(__FUNCTION__);setName("xiaoming");return m_name;}signals:void sigNameChanged(QString name);private:QString m_name = "zhangsan";};//第二,定義單例類型提供者函數(回調) static QObject *example_qobject_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine) {Q_UNUSED(engine)Q_UNUSED(scriptEngine)qDebug()<<__FUNCTION__;Student *student = new Student();return student; }

調用函數注冊:

qmlRegisterSingletonType<Student>("Qt.example.qobjectSingleton", 1, 0, "MyApi", example_qobject_singletontype_provider);

在 QML 中使用:

import QtQuick 2.0 import Qt.example.qobjectSingleton 1.0Item {id: rootproperty string someValue: MyApi.nameComponent.onCompleted: {console.log("someValue = ",someValue)someValue = MyApi.doSomething()console.log("someValue = ",someValue)} }

運行代碼,輸出如下:

example_qobject_singletontype_provider qml: someValue = zhangsan doSomething qml: someValue = xiaoming

注意,由于singleton類型沒有關聯的QQmlContext對象,因此在注冊為單例類型實現的QObject衍生類型的函數內,QML上下文和引擎信息不可用。

3.int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName)

該函數可用于在從uri導入的庫中注冊名為qmlName的單例類型,其版本號由versionMajor和versionMinor組成。該類型由位于url的QML文件定義。該網址必須是絕對網址。

另外,該類型的QML文件在其導入語句中必須包含編譯指令Singleton語句。

單例類型可以通過它所注冊的類型名稱來引用,并且此類型名稱可以用作Connections類型中的目標,或者用作任何其他類型的id。單例類型屬性不能被別名。
看看示例:

//首先,定義提供該功能的QML單例類型。 pragma Singleton import QtQuick 2.0 Item {property int testProp1: 125 } //其次,通過在初始化函數中調用此函數來注冊QML單例類型。 qmlRegisterSingletonType(QUrl("file:///absolute/path/SingletonType.qml"), "Qt.example.qobjectSingleton", 1, 0, "RegisteredSingleton");

為了在QML中使用已注冊的單例類型,必須導入單例類型。

import QtQuick 2.0 import Qt.example.qobjectSingleton 1.0 Item {id: rootproperty int someValue: RegisteredSingleton.testProp1 }

關于單例類型導入先介紹到這里。

總結

以上是生活随笔為你收集整理的Qt 从C ++定义QML类型(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产吃瓜黑料一区二区 | 黄色avv| 91av综合| 成人a视频 | 成人毛片一区二区三区 | 国产成人激情 | 日韩欧美精品在线视频 | 婷婷丁香综合网 | 天天射天天色天天干 | 97在线国产| 国产尤物视频 | 欧美草逼视频 | 做暧暧视频在线观看 | 国产精品国产一区 | 91色啪| 亚洲欧美自偷自拍 | 黄色片在线免费看 | 久久性生活片 | 久久久久久久久久久国产精品 | 少妇脚交调教玩男人的视频 | 天堂网站| 国产这里有精品 | 国内自拍第三页 | 国产精品免费av | 国产不卡在线播放 | 久久精品视频16 | 精品人妻一区二区三区四区久久 | 国产粉嫩一区二区三区 | 一区二区天堂 | a视频在线免费观看 | 久久久噜噜噜久久中文字幕色伊伊 | 极品美女一区二区三区 | 成年精品 | 久久久久久蜜桃一区二区 | 色免费看 | 亚洲天堂2014 | 国产xxxx裸体xxx免费 | 日韩精品一区二区三区中文字幕 | 国产精品揄拍100视频 | xxxxx日韩| 天天摸天天 | 日本ww色 | 五十路在线| 91伦理 | 久久综合久色欧美综合狠狠 | 成人18在线 | 在线免费日韩av | 国产色视频在线 | 国产精品视频网址 | 欧美激情国产一区 | 成人亚洲 | 一级全黄毛片 | 亚洲一区二区三区视频 | 777片理伦片在线观看 | free性中国hd国语露脸 | av手机在线观看 | 女人脱了内裤趴开腿让男躁 | 国产99久 | 日本少妇色视频 | 亚洲精品久久久久久久久久久久久 | 午夜影院体验区 | 午夜一区二区三区免费观看 | 青青草视频免费观看 | 一级做a免费 | 成人免费网站www网站高清 | 欧美日韩精品一区二区在线播放 | 国产精品国产三级国产在线观看 | 黄色美女免费网站 | 天天摸天天插 | 色天天综合网 | 亚洲午夜久久久久 | 亚洲综合伊人 | 日韩一区二区视频在线播放 | 特级西西444www高清大胆免费看 | 国产手机在线视频 | 97人人超| 亚洲 自拍 另类 欧美 丝袜 | 金鱼妻日剧免费观看完整版全集 | 国内精品久久久久久久久久久 | av国产精品 | 精品少妇一区二区三区在线观看 | 日韩 欧美 综合 | 亚洲国产欧美一区二区三区深喉 | 亚洲香蕉中文网 | 无码一区二区 | 四虎在线网址 | 日韩久久久久久久久久久 | 免费黄色在线观看 | 交做爰xxxⅹ性爽 | 老司机成人免费视频 | 精品96久久久久久中文字幕无 | 日韩精品一区二区视频 | 黄色片网站免费看 | 老女人综合网 | 国产一区激情 | 长篇乱肉合集乱500小说日本 | 91av在线视频观看 | 国产乱淫a∨片免费观看 | 日本成人福利视频 |