欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++與QML交互的項目實踐

 更新時間:2023年09月06日 10:00:10   作者:hsy12342611  
本文主要介紹了C++與QML交互的項目實踐,將詳細介紹C++與QML的交互方式,包括在QML中調(diào)用C++函數(shù)和在C++中訪問QML元素,具有一定的參考價值,感興趣的可以了解一下

一直對于QT的理解和使用都停留在主窗口程序和控制臺程序,雖然QT的新東西QML聽過也接觸過,但是基本上沒梳理過調(diào)用流程。趁著舊項目要使用QML技術(shù),現(xiàn)在就將C++和QML交互進行總結(jié)。

在C++和QML中均可以定義信號和槽,并且均可以完成信號和槽的綁定

一. QML中使用C++業(yè)務(wù)類

基本流程如下:

1.將C++注冊進入QML引擎,C++類型在qml中當(dāng)成一個子組件使用

2.在qml中完成信號與槽的綁定

測試代碼:

1.QML定義

main.qml

import QtQuick 2.7
import QtQuick.Window 2.2
import WorkClass 1.0
Window {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    signal qmlSignal1
    signal qmlSignal2(string strValue, int iValue)
    MainForm {
        anchors.fill: parent
        mouseArea.onClicked: {
            Qt.quit();
        }
    }
    MouseArea{
        anchors.fill: parent
        acceptedButtons: Qt.LeftButton | Qt.RightButton
        onClicked: {
            if(mouse.button === Qt.LeftButton){
                console.log(' Qt.LeftButton')
                bussiness.strValue = "HelloCpp"
                bussiness.intValue = 2022
                bussiness.sendSignal()
            }else{
                console.log(' Qt.RightButton')
                root.qmlSignal1()
                root.qmlSignal2('hesy', 2000)
            }
        }
    }
    //加載子頁面qrcode.qml
    //Loader {
    //    id:accountQRCode
    //    source:"qrcode.qml"
    //    x:(root.width - root.height / 3) / 2
    //    y:root.height / 3
    //    visible: true
    //}
    CBusiness{
        id: bussiness
        property int addpro: 0
        onIntValueChanged: {
            console.log('qml onIntValueChanged', "begin change addpro ", addpro)
            addpro++
            console.log('qml onIntValueChanged', addpro)
        }
        onAddproChanged: {
            console.log('qml onAddFun', addpro)
        }
    }
    Component.onCompleted: {
        bussiness.onSignal1.connect(function(){console.log('no name qml function')})
        bussiness.onSignal2.connect(qmlProcess1)
        root.qmlSignal1.connect(bussiness.slot1)
        root.qmlSignal2.connect(bussiness.slot2)
        console.log('Component.onCompleted')
    }
    function qmlProcess1(str, value){
        console.log('qmlProcess1', str, value)
    }
}

備注:

另外在qml中也可以使用Connections綁定C++業(yè)務(wù)類函數(shù)和qml中的方法,例如 qrcode.qml,其中target:bussiness代表上面的id: bussiness,這樣main.qml中包含qrcode.qml,實現(xiàn)了qml之間的調(diào)用,以及多個qml和C++之間的調(diào)用。

import QtQuick 2.0
Item {
    Image {
        id: qrcode
        sourceSize.width: parent.width
        sourceSize.height: parent.height
        source: ""
    }
    Text {
        id: tips
        x: parent.x
        y: parent.y
        text: qsTr("請掃碼")
        font.pixelSize: 24
        visible: false
    }
    Connections {
        target:bussiness
        onAccountQRCodeGenerated: {
            console.log("onAccountQRCodeGenerated invoke !");
            qrcode.source = "image://qrcode/account"
        }
        onAccountScannedSuccess: {
            console.log("onAccountScannedSuccess invoke!");
            qrcode.visible = false
            tips.visible = true
        }
        onAccountLoginSuccess: {
            console.log("onAccountLoginSuccess invoke !");
            tips.text = qsTr("登錄成功, 歡迎!")
        }
    }
}

C++中通過發(fā)射信號調(diào)用qml中方法,對應(yīng)方法名為on+大寫字母開頭函數(shù)

emit accountQRCodeGenerated();
emit accountScannedSuccess();
emit accountLoginSuccess();

2.C++業(yè)務(wù)類定義和實現(xiàn)

cbusiness.h

#ifndef CBUSINESS_H
#define CBUSINESS_H
#include <QObject>
class CBusiness : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString strValue READ getStrValue WRITE setStrValue NOTIFY strValueChanged)
    Q_PROPERTY(int intValue READ getIntValue WRITE setIntValue NOTIFY intValueChanged)
public:
    explicit CBusiness(QObject *parent = 0);
    Q_INVOKABLE void sendSignal();
    void setStrValue(QString strValue);
    QString getStrValue() const;
    void setIntValue(int intValue);
    int getIntValue() const;
signals:
    void signal1();
    void signal2(QString strValue, int intValue);
    void strValueChanged(QString strValue);
    void intValueChanged(int intValue);
public slots:
    void slot1();
    void slot2(QString strValue, int intValue);
private:
    //類的屬性
    QString m_strValue;
    int m_intValue;
};
#endif // CBUSINESS_H

cbusiness.cpp

#include "cbusiness.h"
#include <QDebug>
CBusiness::CBusiness(QObject *parent) : QObject(parent), m_strValue(""), m_intValue(0)
{
}
void CBusiness::sendSignal()
{
    qDebug() << "CBusiness::" << __FUNCTION__;
    emit signal1();
    emit signal2(m_strValue, m_intValue);
}
void CBusiness::setStrValue(QString strValue)
{
    qDebug() << "CBusiness::" << __FUNCTION__ << strValue;
    m_strValue = strValue;
    emit strValueChanged(strValue);
    qDebug()<< "CBusiness::" << "emit strValueChanged" << endl;
}
QString CBusiness::getStrValue() const
{
    qDebug() << "CBusiness::" << __FUNCTION__;
    return m_strValue;
}
void CBusiness::setIntValue(int intValue)
{
    qDebug() << "CBusiness::" << __FUNCTION__;
    m_intValue = intValue;
    emit intValueChanged(intValue);
    qDebug()<< "CBusiness::" << "emit intValueChanged";
}
int CBusiness::getIntValue() const
{
    qDebug() << "CBusiness::" << __FUNCTION__;
    return m_intValue;
}
void CBusiness::slot1()
{
    qDebug() << "CBusiness::" << __FUNCTION__;
}
void CBusiness::slot2(QString strValue, int intValue)
{
    qDebug() << "CBusiness::" << __FUNCTION__;
    qDebug() << "CBusiness:: " << strValue << "  " << intValue;
}

3.主調(diào)函數(shù)

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "cbusiness.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    //qmlRegisterType注冊C++類型至QML
    //arg1:import時模塊名
    //arg2:主版本號
    //arg3:次版本號
    //arg4:QML類型名
    qmlRegisterType<CBusiness>("WorkClass", 1, 0, "CBusiness");
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}

4.測試結(jié)果

鼠標左鍵點擊:

 說明:

信號和槽的綁定在qml中完成,鼠標左鍵按下,首先打?。簈ml: Qt.LeftButton

bussiness.strValue = "HelloCpp" 觸發(fā) CBusiness::setStrValue(

因為如下:

Q_PROPERTY(QString strValue READ getStrValue WRITE setStrValue NOTIFY strValueChanged)

此處= "HelloCpp" 其實是調(diào)用的setStrValue

)調(diào)用

bussiness.intValue = 2022觸發(fā)CBusiness::setIntValue(

因為如下:

Q_PROPERTY(int intValue READ getIntValue WRITE setIntValue NOTIFY intValueChanged)

此處= 2022其實是調(diào)用的setIntValue

)調(diào)用, 然后調(diào)用emit strValueChanged(strValue);,觸發(fā)qml中 onIntValueChanged調(diào)用,接著addpro++觸發(fā)onAddproChanged調(diào)用

最后調(diào)用CBusiness::sendSignal(),觸發(fā)emit signal1(); emit signal2(m_strValue, m_intValue);信號,調(diào)用qml的槽 

function(){console.log('no name qml function')

function qmlProcess1(str, value)

鼠標右鍵點擊:

 說明:

鼠標右鍵,通過qml信號調(diào)用到c++的槽函數(shù),并且還傳遞參數(shù)給c++

二.C++使用QML

基本流程如下:

1.在C++中獲得qml對象指針

2.在C++中完成信號和槽的綁定

測試代碼:

1.QML定義

main.qml

import QtQuick 2.7
import QtQuick.Window 2.2
Item {
    id: root
    visible: true
    width: 640
    height: 480
    //title: qsTr("Hello World")
    property string msg: "I am QML Item"
    signal callCpp(string arg1, string arg2)
    MainForm {
        anchors.fill: parent
        mouseArea.onClicked: {
            Qt.quit();
        }
    }
    Rectangle {
        anchors.fill: parent
        color: "blue"
        objectName: "rect"
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.log("onClicked, callCpp")
            root.callCpp(root.msg, "notify cpp")
        }
    }
    onHeightChanged: {
        console.log("onHeightChanged execute")
    }
    onWidthChanged: {
        console.log("onWidthChanged execute")
    }
    //QML中的方法可以被cpp調(diào)用,也可以作為槽函數(shù)
    function qmlFun(val_arg) {
        console.log("qmlFun execute", val_arg, "return qmlFun_return_result")
        return "qmlFun_return_result"
    }
    //注意槽函數(shù)參數(shù)為var類型
    function invokeFromCpp(arg1, arg2) {
        console.log("invokeFromCpp execute ", arg1, arg2)
    }
}

2.C++業(yè)務(wù)類定義和實現(xiàn)

cbusiness.h

#ifndef CBUSINESS_H
#define CBUSINESS_H
#include <QObject>
class CBusiness : public QObject
{
    Q_OBJECT
public:
    explicit CBusiness(QObject *parent = 0);
signals:
    void callQml(const QVariant &arg1,const QVariant &arg2);
public slots:
    void invokeFromQml(const QString &arg1,const QString &arg2);
};
#endif // CBUSINESS_H

cbusiness.cpp

#include "cbusiness.h"
#include <QDebug>
CBusiness::CBusiness(QObject *parent) : QObject(parent)
{
}
void CBusiness::invokeFromQml(const QString &arg1,const QString &arg2)
{
    qDebug() << "CBusiness::" << __FUNCTION__ << arg1 << arg2;
    qDebug() << "CBusiness::" << __FUNCTION__ << " emit callQml";
    emit callQml("I am cpp", "notify qml");
}

3.主調(diào)函數(shù)

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlProperty>
#include <QQuickView>
#include <QQuickItem>
#include <QMetaObject>
#include <QDebug>
#include "cbusiness.h"
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    /*
    可以用QQmlComponent\QQuickView\QQuickWidget的C++代碼加載QML文檔
    當(dāng)使用QQuickView時,qml的根不能是Window
    */
    QQuickView view(QUrl("qrc:/main.qml"));
    view.show();
    // 獲取到qml根對象的指針
    QObject *qmlObj = view.rootObject();
        /*
        修改qml屬性值的方法
        QObject::setProperty()  QQmlProperty  QMetaProperty::write()
        */
    // 通過QObject設(shè)置屬性值
    qDebug() << "cpp: " << "set qml property height";
    QQmlProperty(qmlObj, "height").write(500);  //qmlObj->setProperty("height",500);
    // 通過QObject獲取屬性值
    qDebug() << "cpp: " << "get qml property height" << qmlObj->property("height").toDouble();
    // C++訪問qml的其它屬性
    qDebug() << "cpp: " << "get qml property msg" << qmlObj->property("msg").toString();
    // 獲取QQuickItem
    QQuickItem *item = qobject_cast<QQuickItem*>(qmlObj);
    // 通過QQuickItem設(shè)置屬性值
    qDebug() << "cpp: " << "set qml property width";
    item->setWidth(300);
    // 通過QQuickItem獲取屬性值
    qDebug() << "cpp: " << "get qml property width" << item->width();
    // 通過object name訪問加載的QML對象
    // QObject::findChildren()可用于查找具有匹配object name屬性的子項
    QObject *qmlRect = qmlObj->findChild<QObject*>("rect");
    if(qmlRect)
    {
        qDebug() << "cpp: " << "get rect color" << qmlRect->property("color");
    }
    // C++調(diào)用QML方法
    QVariant valReturn;
    QVariant valArg = "I am cpp";
    //Q_RETURN_ARG()和Q_Arg()參數(shù)必須制定為QVariant類型
    QMetaObject::invokeMethod(qmlObj, "qmlFun",
                              Q_RETURN_ARG(QVariant,valReturn),
                              Q_ARG(QVariant,valArg));
    qDebug() << "cpp: " << "QMetaObject::invokeMethod result" << valReturn.toString(); //qml函數(shù)中返回“ok”
    CBusiness cppObj;
    // cpp和qml信號與槽關(guān)聯(lián)
    // qml信號綁訂cpp的槽,用QString類型
    QObject::connect(qmlObj, SIGNAL(callCpp(QString, QString)), &cppObj, SLOT(invokeFromQml(QString, QString)));
    //關(guān)聯(lián)cpp信號與qml槽
    // cpp的信號綁定qml槽,用QVariant類型
    QObject::connect(&cppObj, SIGNAL(callQml(QVariant, QVariant)), qmlObj, SLOT(invokeFromCpp(QVariant, QVariant)));
    return app.exec();
}

4.測試結(jié)果

信號和槽的綁定在c++代碼中完成,在c++中可以修改qml的屬性,獲取qml的屬性,調(diào)用qml的方法,傳遞和獲取參數(shù)均可以

 鼠標點擊

 鼠標點擊后,通過qml的信號callCpp調(diào)用c++的槽函數(shù)invokeFromQml,然后再通過c++的信號函數(shù)callQml調(diào)用qml的槽函數(shù)invokeFromCpp

三.QVariant中方法canConvert和convert使用總結(jié)

1.canConvert只是報告QVariant進行兩個類型之間轉(zhuǎn)換的能力,例如QString和Int類型之間的轉(zhuǎn)換,關(guān)注類型
2.convert判斷的是QVariant進行兩個類型的數(shù)據(jù)之間轉(zhuǎn)換的能力,例如“123”和123之間的轉(zhuǎn)換,關(guān)注數(shù)據(jù)

舉例:

QString str1 = "Qt5.7.0";
QVariant var1 = str1;
qDebug() << var1.canConvert(QVariant::Int); // true
qDebug() << var1.convert(QVariant::Int); // false
qDebug() << var1.toString(); // "0"
var1 = str1;
qDebug() << var1.convert(QVariant::String); // true
qDebug() << var1.toString(); // "Qt5.7.0"
QString str2 = "789";
QVariant var2 = str2;
qDebug() << var2.canConvert(QVariant::Int); // true
qDebug() << var2.convert(QVariant::Int); // true
qDebug() << var2.toString(); // "789"

 到此這篇關(guān)于C++與QML交互的項目實踐的文章就介紹到這了,更多相關(guān)C++ QML交互內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)defer聲明方法詳解

    C++實現(xiàn)defer聲明方法詳解

    這篇文章主要介紹了C++實現(xiàn)defer聲明,在和朋友交談時候,無意間了解到Go語言的defer,發(fā)現(xiàn)挺有意思的。和智能指針類似,當(dāng)出了作用域后,被defer修飾的操作才會執(zhí)行
    2022-11-11
  • C語言文件操作詳解

    C語言文件操作詳解

    這篇文章主要介紹了C語言 文件操作解析詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-10-10
  • C++?Boost?Conversion超詳細講解

    C++?Boost?Conversion超詳細講解

    Boost是為C++語言標準庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標準庫的后備,是C++標準化進程的開發(fā)引擎之一,是為C++語言標準庫提供擴展的一些C++程序庫的總稱
    2022-11-11
  • C++編程模板匹配超詳細的識別手寫數(shù)字實現(xiàn)示例

    C++編程模板匹配超詳細的識別手寫數(shù)字實現(xiàn)示例

    大家好!本篇文章是關(guān)于手寫數(shù)字識別的,接下來我將在這里記錄我的手寫數(shù)字識別的從零到有,我在這里把我自己的寫代碼過程發(fā)出來,希望能幫到和我一樣努力求知的人
    2021-10-10
  • C++學(xué)習(xí)筆記之pimpl用法詳解

    C++學(xué)習(xí)筆記之pimpl用法詳解

    在編寫穩(wěn)定代碼是,管理好代碼間的依賴性是不可缺少的一個環(huán)節(jié)。特別是庫文件的編寫中,減少代碼間的依賴性可以提供一個“干凈”的接口。下面這篇文章主要給大家介紹了關(guān)于C++中pimpl用法的相關(guān)資料,需要的朋友可以參考下。
    2017-08-08
  • C語言實現(xiàn)簡單的通訊錄管理系統(tǒng)

    C語言實現(xiàn)簡單的通訊錄管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 關(guān)于C/C++中可變參數(shù)的詳細介紹(va_list,va_start,va_arg,va_end)

    關(guān)于C/C++中可變參數(shù)的詳細介紹(va_list,va_start,va_arg,va_end)

    可變參數(shù)的函數(shù)原理其實很簡單,而va系列是以宏定義來定義的,實現(xiàn)跟堆棧相關(guān).我們寫一個可變函數(shù)的C函數(shù)時,有利也有弊,所以在不必要的場合,我們無需用到可變參數(shù)。如果在C++里,我們應(yīng)該利用C++的多態(tài)性來實現(xiàn)可變參數(shù)的功能,盡量避免用C語言的方式來實現(xiàn)
    2013-10-10
  • 從匯編看c++的默認析構(gòu)函數(shù)的使用詳解

    從匯編看c++的默認析構(gòu)函數(shù)的使用詳解

    本篇文章是對c++中默認析構(gòu)函數(shù)的使用進行了詳細的分析介紹。需要的朋友參考下
    2013-05-05
  • 簡單講解c++ vector

    簡單講解c++ vector

    這篇文章主要介紹了c++ vector的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下
    2020-09-09
  • 在C語言中使用對數(shù)函數(shù)的方法

    在C語言中使用對數(shù)函數(shù)的方法

    這篇文章主要介紹了在C語言中使用對數(shù)函數(shù)的方法,包括以e為底和以10為底的對數(shù)計算,需要的朋友可以參考下
    2015-08-08

最新評論