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

QML與C++交互之創(chuàng)建自定義對象的實(shí)現(xiàn)

 更新時間:2025年07月07日 11:01:42   作者:cpp_learners  
本文介紹了在QML中通過C++定義全局對象的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在qml中,我們一般都是希望使用qml做界面展示,而數(shù)據(jù)處理轉(zhuǎn)由c++處理;

在此篇博客,將介紹如何在c++中給qml定義全局對象;在c++中如何定義對象給qml使用。

1 給qml定義全局對象

正常我們定義了一個qml項(xiàng)目后,main函數(shù)是這樣的:

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include <QQmlContext>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

QQmlApplicationEngine 是 Qt 框架中用于加載和運(yùn)行基于 QML 的應(yīng)用程序的核心類,結(jié)合了 QQmlEngine 和 QQmlComponent 的功能,支持從單個 QML 文件加載應(yīng)用程序,并實(shí)現(xiàn) C++ 與 QML 的雙向通信。

那么,就可以使用QQmlApplicationEngine去獲得全局上下文對象QQmlContext,通過使用上下文對象,就可以給qml設(shè)置一個全局的變量值;

獲得上下文對象:

// 獲得全局對象,上下文對象
QQmlContext *context = engine.rootContext();

給qml設(shè)置一個全局變量:

// 給qml設(shè)置一個全局變量;
context->setContextProperty("SCREEN_WIDTH", 800);

這樣,就可以在qml中使用該變量了,例如在mian.qml文件內(nèi)使用:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.14

Window {
    id: root
    visible: true
    width: SCREEN_WIDTH    // 直接使用
    height: 500
    title: qsTr("Hello World")
    color: "white"

    // 如果qml內(nèi)部有定義重名變量,那么會優(yōu)先使用qml內(nèi)部定義的變量,而不會使用C++定義的變量
    //property int SCREEN_WIDTH: 500
}

注意:如果qml內(nèi)部有定義重名變量,那么會優(yōu)先使用qml內(nèi)部定義的變量;另外,定義全局變量會有性能消耗問題。

2 在c++中定義對象給qml使用

自定義C++類MyObject繼承自QObject;有兩個成員變量,int m_iValue 和 QString m_sString;并且給他倆定義get和set方法;另外在定義兩個信號;最后通過Q_PROPERTY將兩個成員變量暴露給元對象。

myobject.h

#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <QObject>

class MyObject : public QObject
{
    Q_OBJECT

public:
    MyObject(QObject *parent = nullptr);  // 構(gòu)造函數(shù)
    ~MyObject();

    const int &iValue() const;
    void setIIValue(const int &newIValue);

    const QString &sString() const;
    void setSString(const QString &newSString);

signals:
    void iValueChanged();
    void sStringChanged();

private:
    int m_iValue;
    QString m_sString;

    Q_PROPERTY(int iValue READ iValue WRITE setIIValue NOTIFY iValueChanged)
//    Q_PROPERTY(QString sString READ sString WRITE setSString NOTIFY sStringChanged)
    // 如果值是函數(shù)內(nèi)部成員變量的值,可使用MEMBER去設(shè)置,與READ sString WRITE setSString實(shí)現(xiàn)效果一致
    Q_PROPERTY(QString sString MEMBER m_sString NOTIFY sStringChanged)
};

#endif // MYOBJECT_H

myobject.cpp

#include "myobject.h"


MyObject::MyObject(QObject *parent) : QObject(parent)
{

}

MyObject::~MyObject()
{

}

const int &MyObject::iValue() const
{
    return m_iValue;
}

void MyObject::setIIValue(const int &newIValue)
{
    if (m_iValue == newIValue) {
        return;
    }

    m_iValue = newIValue;
    emit iValueChanged();
}

const QString &MyObject::sString() const
{
    return m_sString;
}

void MyObject::setSString(const QString &newSString)
{
    if (m_sString == newSString) {
        return;
    }

    m_sString = newSString;
    emit sStringChanged();
}

Q_PROPERTY的參數(shù)講解

Q_PROPERTY(int iValue READ iValue WRITE setIIValue NOTIFY iValueChanged)

int iValue 指定是給qml使用的變量名,推薦與c++類成員變量名類似;

READ iValue 指的是通過iValue函數(shù)去讀取值;

WRITE setIIValue 指的是通過setIIValue函數(shù)去修改iValue值;

NOTIFY iValueChanged 指的是當(dāng)iValue值被修改后,會發(fā)送的信號;

然后main函數(shù)中使用qmlRegisterType函數(shù)對自定義類進(jìn)行注冊,注冊后,就可以在qml那邊導(dǎo)入使用了。

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include <QQmlContext>
#include "myobject.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    // 獲得全局對象,上下文對象
    QQmlContext *context = engine.rootContext();
    // 給qml設(shè)置一個全局變量;如果qml內(nèi)部有定義重名變量,那么會優(yōu)先使用qml內(nèi)部定義的變量;另外,定義全局變量會有性能問題
    context->setContextProperty("SCREEN_WIDTH", 800);

    // 注冊,在需要使用的地方 import MyObj 1.0
    qmlRegisterType<MyObject>("MyObj", 1, 0, "MyObject");

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

其中,MyObj是給qml那邊導(dǎo)入時使用的模塊名字,1 和 0 指的是版本,最后的MyObject就是自定義類名;

然后就可以在qml中 import MyObj 1.0 導(dǎo)入使用了。

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.14

import MyObj 1.0    // 導(dǎo)入自定義模塊

Window {
    id: root
    visible: true
    width: SCREEN_WIDTH
    height: 500
    title: qsTr("Hello World")
    color: "white"


    MyObject {
        iValue: 20
        sString: "this is a custom obj.";

        Component.onCompleted: {
            console.log("iValue:", 20, "  sString:", sString)
        }
    }
}

3 番外

Q_PROPERTY為什么要指定NOTIFY信號呢?

在這里與qml的綁定有關(guān)系;

在qml中,當(dāng)給一個變量以冒號':'方式賦值時,這兩個變量是互相綁定的;例如:

property int testValue: myObj.iValue

當(dāng)myObj.iValue被修改時,就會觸發(fā)信號通知testValue也一并修改!

案例代碼:定義變量testValue使用冒號被myObject.iValue賦值,定義按鈕在onClicked槽函數(shù)中修改myObj.iValue值,觀察testValue是否也被修改;

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.14

import MyObj 1.0    // 導(dǎo)入自定義模塊

Window {
    id: root
    visible: true
    width: SCREEN_WIDTH
    height: 500
    title: qsTr("Hello World")
    color: "white"

    property int testValue: myObj.iValue    // 綁定了

    onTestValueChanged: {
        console.log("testValue:", testValue)
    }

    Button {
        width: 100; height: 50
        onClicked: {
           myObj.iValue = 50;
        }
    }

    MyObject {
        id: myObj

        iValue: 20
        sString: "this is a custom obj.";

        Component.onCompleted: {
            console.log("iValue:", 20, "  sString:", sString)
        }
    }
}

當(dāng)點(diǎn)擊按鈕后,修改的是myObj.iValue,但testValue也一并被修改了,由此證明,使用冒號賦值時,他倆是會綁定在一起的。 

注意,使用 = 賦值時,不會有綁定的效果?。?!

到此這篇關(guān)于QML與C++交互之創(chuàng)建自定義對象的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)QML與C++交互內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

太湖县| 洛宁县| 铁岭市| 潮安县| 四会市| 新昌县| 年辖:市辖区| 文水县| 崇阳县| 乌兰浩特市| 抚顺县| 紫金县| 额济纳旗| 保靖县| 新晃| 临西县| 林西县| 宁武县| 建平县| 玉环县| 陈巴尔虎旗| 丰镇市| 北宁市| 高阳县| 贺兰县| 华阴市| 富蕴县| 和田县| 恩施市| 普兰店市| 房产| 萨迦县| 吉木乃县| 南宁市| 鸡泽县| 灵山县| 阜新市| 犍为县| 龙游县| 姚安县| 伽师县|