最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

將?C++?類型屬性暴露給?QML

 更新時(shí)間:2021年12月14日 17:03:18   作者:友善啊,朋友  
這篇文章主要介紹了將?C++?類型屬性暴露給?QML,?QML?是一種基于?JavaScript?的聲明式語言。在?Qt5中,QML有了長足進(jìn)步,并且同?C++?并列成為?Qt?的首選編程語言下面一起進(jìn)入文章學(xué)習(xí)?QML的條件下也看看如何將將?C++?類型屬性暴露給?QML,需要的朋友可以參考一下

可以使用 C++ 代碼中定義的功能輕松擴(kuò)展 QML。由于 QML 引擎與 Qt 元對象系統(tǒng)的緊密集成,QObject 派生類公開的任何功能都可以從 QML 代碼訪問。這使得 C++ 數(shù)據(jù)和函數(shù)可以直接從 QML 訪問,通常幾乎不需要修改。

QML 引擎能夠通過元對象系統(tǒng)反射 QObject 實(shí)例。這意味著任何 QML 代碼都可以訪問 QObject 派生類的實(shí)例的以下成員:

  • 屬性
  • 方法(前提是它們是 public slots 或用 Q_INVOKABLE 標(biāo)記)
  • 信號

(此外,如果枚舉是用 Q_ENUMS 聲明的,則也可以訪問)

一、數(shù)據(jù)類型處理和所有權(quán)

任何從 C++ 傳輸?shù)?QML 的數(shù)據(jù),無論是作為屬性值、方法參數(shù)或返回值,還是信號參數(shù)值,都必須是 QML 引擎支持的類型。

默認(rèn)情況下,引擎支持許多 Qt C++ 類型,并且可以在從 QML 使用時(shí)自動(dòng)適當(dāng)?shù)剞D(zhuǎn)換它們。

1.1、暴露屬性

可以使用 Q_PROPERTY() 宏為任何 QObject 派生類指定屬性。

例如,下面是一個(gè)具有作者屬性的 Message 類。 正如 Q_PROPERTY 宏調(diào)用所指定的,這個(gè)屬性可以通過 author() 方法讀取,通過 setAuthor() 方法寫入:

注意:不要使用 typedef 或 using 指定 Q_PROPERTY 類型,因?yàn)樗鼈儠煜?moc。 這可能會使某些類型比較失敗。

錯(cuò)誤用法:

using FooEnum = Foo::Enum;
 
class Bar : public QObject 
{
    Q_OBJECT
    Q_PROPERTY(FooEnum enum READ enum WRITE setEnum NOTIFY enumChanged)
};


正確用法:

class Bar : public QObject 
{
    Q_OBJECT
    Q_PROPERTY(Foo::Enum enum READ enum WRITE setEnum NOTIFY enumChanged)
};


暴露屬性實(shí)例:

class Message : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
public:
    void setAuthor(const QString &a) 
    {
        if (a != m_author) 
        {
            m_author = a;
            emit authorChanged();
        }
    }
    QString author() const 
    {
        return m_author;
    }
signals:
    void authorChanged();
private:
    QString m_author;
};


如果在從 C++ 加載名為 MyItem.qml 的文件時(shí)將此類的實(shí)例設(shè)置為上下文屬性:

int main(int argc, char *argv[]) 
{
    QGuiApplication app(argc, argv);
 
    QQuickView view;
    Message msg;
    view.engine()->rootContext()->setContextProperty("msg", &msg);
    view.setSource(QUrl::fromLocalFile("MyItem.qml"));
    view.show();
 
    return app.exec();
}
然

可以從 MyItem.qml 中讀取 author 屬性:

// MyItem.qml
import QtQuick 2.0
 
Text 
{
    width: 100; height: 100
    text: msg.author    // 調(diào)用 Message::author() 來獲取這個(gè)值
 
    Component.onCompleted: 
    {
        msg.author = "Jonah"  // 調(diào)用 Message::setAuthor()    
    }
}


為了實(shí)現(xiàn)C++與 QML 的最大互操作性,任何可寫的屬性都應(yīng)該有一個(gè)關(guān)聯(lián)的 NOTIFY 信號,該信號在屬性值更改時(shí)發(fā)出。這允許屬性與屬性綁定一起使用,這是 QML 的一個(gè)基本特性,它通過在任何依賴項(xiàng)的值發(fā)生變化時(shí)自動(dòng)更新屬性來強(qiáng)制執(zhí)行屬性之間的關(guān)系。即發(fā)出信號會通知 QML 引擎更新任何涉及屬性的綁定。

上面示例中如果 author 屬性可寫但沒有關(guān)聯(lián)的 NOTIFY 信號,則文本值將使用 Message::author() 返回的初始值進(jìn)行初始化,但不會隨此屬性的任何后續(xù)更改而更新。此外,任何從 QML 綁定到屬性的嘗試都會從引擎產(chǎn)生運(yùn)行時(shí)警告。

建議將 NOTIFY 信號命名為 <property>Changed,其中 <property> 是屬性的名稱。QML 引擎生成的關(guān)聯(lián)屬性更改信號處理程序?qū)⑹冀K采用 on<Property>Changed 形式,無論相關(guān) C++ 信號的名稱如何,因此建議信號名稱遵循此約定以避免任何混淆。

1.2、使用通知信號的注意事項(xiàng)

開發(fā)人員應(yīng)確保僅在屬性值實(shí)際更改時(shí)才發(fā)出屬性更改信號。此外,如果一個(gè)屬性或一組屬性不經(jīng)常使用,則允許對多個(gè)屬性使用相同的 NOTIFY 信號。這應(yīng)該小心完成以確保性能不會受到影響。

NOTIFY 信號的存在確實(shí)會產(chǎn)生很小的開銷。在某些情況下,屬性的值是在對象構(gòu)造時(shí)設(shè)置的,隨后不會更改。在這些情況下,可以將 CONSTANT 屬性而不是 NOTIFY 信號添加到屬性聲明中。

CONSTANT 屬性應(yīng)僅用于其值僅在類構(gòu)造函數(shù)中設(shè)置和最終確定的屬性。

1.3、具有對象類型的屬性

對象類型屬性可從 QML 訪問,前提是對象類型已正確注冊到 QML 類型系統(tǒng)。

例如:Message 類型可能具有 MessageBody* 類型的 body 屬性

class Message : public QObject
{
    Q_OBJECT
    Q_PROPERTY(MessageBody* body READ body WRITE setBody NOTIFY bodyChanged)
public:
    MessageBody* body() const;
    void setBody(MessageBody* body);
};
 
class MessageBody : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString text READ text WRITE text NOTIFY textChanged)
// ...
}


假設(shè) Message 類型已在 QML 類型系統(tǒng)中注冊,

允許將其用作 QML 代碼中的對象類型:

Message
{
    // ...
}


如果 MessageBody 類型也注冊到類型系統(tǒng),則可以將 MessageBody 分配給 Message body 屬性:

Message 
{
    body: MessageBody 
    {
        text: "Hello, world!"
    }
}


1.4、具有對象列表類型的屬性

包含 QObject 派生類型列表的屬性也可以暴露給 QML。然而,應(yīng)該使用 QQmlListProperty 而不是 QList<T> 作為屬性類型。 這是因?yàn)?QList 不是 QObject 派生的類型,因此無法通過 Qt 元對象系統(tǒng)提供必要的 QML 屬性特征,例如修改列表時(shí)的信號通知。

例如,下面的 MessageBoard 類有一個(gè) QQmlListProperty 類型的消息屬性,用于存儲 Message 實(shí)例列表:

class MessageBoard : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QQmlListProperty<Message> messages READ messages)
public:
    QQmlListProperty<Message> messages()
    {
        return QQmlListProperty<Message>(this, 0, &MessageBoard::append_message);
    }
 
private:
    static void append_message(QQmlListProperty<Message> *list, Message *msg)
    {
        MessageBoard *msgBoard = qobject_cast<MessageBoard *>(list->object);
        if (msg)
            msgBoard->m_messages.append(msg);
    }
    QList<Message *> m_messages;
};
QQmlListProperty 的模板類類型(在本例中為 Message)必須在 QML 類型系統(tǒng)中注冊。

1.5、分組屬性

任何只讀的對象類型屬性都可以作為分組屬性從 QML 代碼訪問。這可用于公開一組相關(guān)屬性,這些屬性描述了類型的一組屬性。

例如,假設(shè) Message::author 屬性的類型是 MessageAuthor 而不是簡單的字符串,具有 name email 的子屬性:

class MessageAuthor : public QObject
{
    Q_PROPERTY(QString name READ name WRITE setName)
    Q_PROPERTY(QString email READ email WRITE setEmail)
public:
    ...
};
 
class Message : public QObject
{
    Q_OBJECT
    Q_PROPERTY(MessageAuthor* author READ author)
public:
    Message(QObject *parent)
        : QObject(parent), m_author(new MessageAuthor(this))
    {
    }
    MessageAuthor *author() const 
    {
        return m_author;
    }
private:
    MessageAuthor *m_author;
};


可以使用 QML 中的分組屬性語法編寫 author 屬性:

Message 
{
    author.name: "Alexandra"
    author.email: "alexandra@mail.com"
}


分組屬性是只讀的,并且在構(gòu)造時(shí)由父對象初始化為有效值。

分組屬性的子屬性可以從 QML 修改,但分組屬性對象本身永遠(yuǎn)不會改變,

二、暴露方法

QObject 派生類型的任何方法都可以從 QML 代碼訪問,只要它滿足其中一項(xiàng):

  • Q_INVOKABLE() 宏標(biāo)記的公共方法
  • 作為 public slot 的方法

例如,下面的 MessageBoard 類有一個(gè)使用 Q_INVOKABLE 宏標(biāo)記的 postMessage() 方法,以及一個(gè)公共槽的 refresh() 方法:

class MessageBoard : public QObject
{
    Q_OBJECT
public:
    Q_INVOKABLE bool postMessage(const QString &msg) 
    {
        qDebug() << "Called the C++ method with" << msg;
        return true;
    }
 
public slots:
    void refresh() 
    {
        qDebug() << "Called the C++ slot";
    }
};


如果將 MessageBoard 的實(shí)例設(shè)置為文件 MyItem.qml 的上下文數(shù)據(jù),則 MyItem.qml 可以調(diào)用兩個(gè)方法,如下例所示:

int main(int argc, char *argv[]) 
{
    QGuiApplication app(argc, argv);
 
    MessageBoard msgBoard;
    QQuickView view;
    view.engine()->rootContext()->setContextProperty("msgBoard", &msgBoard);
    view.setSource(QUrl::fromLocalFile("MyItem.qml"));
    view.show();
 
    return app.exec();
}
// MyItem.qml
import QtQuick 2.0
 
Item 
{
    width: 100; height: 100
 
    MouseArea 
    {
        anchors.fill: parent
        onClicked: 
        {
            var result = msgBoard.postMessage("Hello from QML")
            console.log("Result of postMessage():", result)
            msgBoard.refresh();
        }
    }
}


如果 C++ 方法具有 QObject* 類型的參數(shù),則可以使用對象 id 或引用該對象的 JavaScript 變量值從 QML 傳遞參數(shù)值。

QML 支持調(diào)用重載的 C++ 函數(shù)。 如果存在多個(gè)同名但參數(shù)不同的 C++ 函數(shù),則會根據(jù)提供的參數(shù)數(shù)量和類型調(diào)用正確的函數(shù)。

當(dāng)從 QML 中的 JavaScript 表達(dá)式訪問時(shí),從 C++ 方法返回的值將轉(zhuǎn)換為 JavaScript 值。

三、暴露信號

QObject 派生類型的任何公共信號都可以從 QML 代碼訪問。

QML 引擎自動(dòng)為從 QML 使用的 QObject 派生類型的任何信號創(chuàng)建信號處理程序。信號處理程序始終命名為 on<Signal>,其中 <Signal> 是信號的名稱,首字母大寫。 信號傳遞的所有參數(shù)都可以通過參數(shù)名稱在信號處理程序中使用。

例如,假設(shè) MessageBoard 類有一個(gè)帶有單個(gè)參數(shù)主題的 newMessagePosted() 信號:

class MessageBoard : public QObject
{
    Q_OBJECT
public:
   // ...
signals:
   void newMessagePosted(const QString &subject);
};


?如果 MessageBoard 類型已注冊到 QML 類型系統(tǒng),則在 QML 中聲明的 MessageBoard 對象可以使用名為 onNewMessagePosted 的信號處理程序接收 newMessagePosted() 信號,并檢查主題參數(shù)值:

MessageBoard 
{
    onNewMessagePosted: (subject)=> console.log("New message received:", subject)
}


與屬性值和方法參數(shù)一樣,信號參數(shù)必須具有 QML 引擎支持的類型。(使用未注冊的類型不會產(chǎn)生錯(cuò)誤,但處理程序?qū)o法訪問參數(shù)值。)

請注意:QML引擎無法區(qū)分名稱相同但參數(shù)不同的信號,類可能有多個(gè)同名的信號,但只有最后一個(gè)信號可以作為 QML 信號訪問。

到此這篇關(guān)于將 C++ 類型屬性暴露給 QML的文章就介紹到這了,更多相關(guān)? C++ 類型屬性暴露給 QML內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++模擬實(shí)現(xiàn)vector的示例代碼

    C++模擬實(shí)現(xiàn)vector的示例代碼

    Vector是一個(gè)能夠存放任意類型的動(dòng)態(tài)數(shù)組,有點(diǎn)類似數(shù)組,是一個(gè)連續(xù)地址空間。本文將用C++模擬實(shí)現(xiàn)vector,感興趣的小伙伴可以了解一下
    2022-08-08
  • Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫清理

    Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫清理

    項(xiàng)目如果需要存儲很多日志記錄比如運(yùn)行日志,時(shí)間長了記錄數(shù)量非常多,數(shù)據(jù)庫體積不斷增大,對應(yīng)數(shù)據(jù)庫表的增刪改查的效率不斷降低,因此需要將早期的數(shù)據(jù)清理。本文將詳細(xì)介紹一下通用數(shù)據(jù)庫清理的實(shí)現(xiàn),需要的可以參考一下
    2022-02-02
  • C語言楊輝三角兩種實(shí)現(xiàn)方法

    C語言楊輝三角兩種實(shí)現(xiàn)方法

    大家好,本篇文章主要講的是C語言楊輝三角兩種實(shí)現(xiàn)方法,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • C++ vector的介紹及常見功能實(shí)現(xiàn)

    C++ vector的介紹及常見功能實(shí)現(xiàn)

    這篇文章主要介紹了C++ vector的介紹及模擬實(shí)現(xiàn),vector在實(shí)際中非常的重要,但在實(shí)際中我們只要熟悉常見的接口就可以了,最重要的是理解他的底層原理,要能夠自己模擬實(shí)現(xiàn)出一個(gè)簡單的vector,本文結(jié)合示例代碼給大家詳細(xì)介紹,需要的朋友可以參考下
    2023-05-05
  • 用C語言實(shí)現(xiàn)貪吃蛇小游戲

    用C語言實(shí)現(xiàn)貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了用C語言實(shí)現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C++使用QTcreator創(chuàng)建動(dòng)態(tài)庫流程

    C++使用QTcreator創(chuàng)建動(dòng)態(tài)庫流程

    在工程中,經(jīng)常會根據(jù)不同的場景需求將類封裝成庫文件,本文主要介紹了C++使用QTcreator創(chuàng)建動(dòng)態(tài)庫流程,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • C語言中函數(shù)與指針的應(yīng)用總結(jié)

    C語言中函數(shù)與指針的應(yīng)用總結(jié)

    本篇文章是對C語言中函數(shù)與指針的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • Qt快速讀取大文件最后一行內(nèi)容解決方案

    Qt快速讀取大文件最后一行內(nèi)容解決方案

    這篇文章主要給大家介紹了關(guān)于Qt如何快速讀取大文件最后一行內(nèi)容的解決方案,文中通過代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Qt具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-01-01
  • C語言全方位講解數(shù)組的使用

    C語言全方位講解數(shù)組的使用

    數(shù)組是一組有序的數(shù)據(jù)的集合,數(shù)組中元素類型相同,由數(shù)組名和下標(biāo)唯一地確定,數(shù)組中數(shù)據(jù)不僅數(shù)據(jù)類型相同,而且在計(jì)算機(jī)內(nèi)存里連續(xù)存放,地址編號最低的存儲單元存放數(shù)組的起始元素,地址編號最高的存儲單元存放數(shù)組的最后一個(gè)元素
    2022-04-04
  • C語言實(shí)現(xiàn)動(dòng)態(tài)愛心代碼

    C語言實(shí)現(xiàn)動(dòng)態(tài)愛心代碼

    這篇文章主要為大家詳細(xì)介紹了如何通過C語言實(shí)現(xiàn)動(dòng)態(tài)愛心的效果,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,還不快跟隨小編一起get李峋同款愛心代碼
    2022-11-11

最新評論

洛南县| 凤山市| 晋江市| 唐山市| 安陆市| 邻水| 陆良县| 浑源县| 乌海市| 上高县| 宁海县| 阿克陶县| 东山县| 沧源| 佛冈县| 徐汇区| 陵川县| 泌阳县| 和林格尔县| 彰武县| 扎囊县| 天门市| 织金县| 吴江市| 织金县| 庆城县| 龙泉市| 南康市| 米林县| 甘泉县| 夏河县| 玛沁县| 南郑县| 定日县| 延长县| 浪卡子县| 潢川县| 丰都县| 河西区| 平陆县| 晋江市|