QML与C++交互2

在QML与C++的交互中,主要有两种方式:在C++中调用QML的方法 和在QML中调用C++的方法。以下是具体的实现方法。

在C++中调用QML的方法

首先,我们需要在QML文件中定义一个函数,然后在C++代码中调用它。

示例

cpp 复制代码
//QML main.qml文件
import QtQuick 2.12
import QtQuick.Window 2.12

Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")

Rectangle {
id: rect
width: 100
height: 100
color: "red"

function changeColor(newColor) {
rect.color = newColor;
}
}
}
cpp 复制代码
//c++端  main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDebug>

int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
engine.load(url);

QObject *rootObject = engine.rootObjects().first();
QVariant returnedValue;
QVariant msg = "blue";
QMetaObject::invokeMethod(rootObject, "changeColor",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, msg));

return app.exec();
}

在QML中调用C++的方法

我们需要在C++类中定义一个方法,并使用Q_INVOKABLE宏标记它,然后在QML文件中调用该方法。

示例

Mclass.h

cpp 复制代码
#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>

class Myclass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
    Q_PROPERTY(int value READ getValue WRITE setValue NOTIFY valueChanged)
public:
    Q_INVOKABLE void function1();
    static Myclass* getInstance();
    explicit Myclass(QObject *parent = nullptr);
    const QString &name() const;
    void setName(const QString &newName);
    int getValue() const;
    void setValue(int newValue);
public slots:
     void setspeed(int setspeed);//槽函数



signals:

    void nameChanged();

    void valueChanged();

private:
    QString m_name;
    int value=0;


};

#endif // MYCLASS_H

Myclass.cpp

cpp 复制代码
#include "myclass.h"
#include "QDebug"
void Myclass::function1()
{
    qDebug()<<"qml端调用c++函数";
}

Myclass *Myclass::getInstance()
{
    static Myclass* class1=new Myclass;
    return class1;
}

Myclass::Myclass(QObject *parent) : QObject(parent)
{

}

const QString &Myclass::name() const
{
    return m_name;
}

void Myclass::setName(const QString &newName)
{
    if (m_name == newName)
        return;
    m_name = newName;
    emit nameChanged();
}

int Myclass::getValue() const
{
    return value;
}

void Myclass::setValue(int newValue)
{
    if (value == newValue)
        return;
    value = newValue;
    emit valueChanged();
}

void Myclass::setspeed(int setspeed)
{   this->value=setspeed;
    qDebug()<<"qml槽函数运行"<<setspeed;
}

第一步就完成了,那如何通过注册好以后在qml中如何调用C++的函数?

第二步:就是将调用函数前要加入Q_INVOKABLE 宏,这样这个函数才能够在qml中调用

最后一步,通过在main.cpp中注册某个类,通过这个注册好的版本号引入对应要调用的qml文件中,然后直接通过 类.函数 调用对应的函数

main.cpp中注册类

cpp 复制代码
#include <QQmlApplicationEngine>
#include<QQmlContext>
#include <QLoggingCategory>
#include "myclass.h"
#include <QIcon>
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);//初始化 Qt 应用程序。参数 argc 和 argv 用于命令行参数。

//    app.setWindowIcon(QIcon("icon/icon.png"));

    QQmlApplicationEngine engine;//创建一个 QML 应用程序引擎实例,负责加载 QML 代码

    QLoggingCategory::setFilterRules(QStringLiteral("qt.qml.binding.removal.info=true"));

    //注册属性到 qml      不常用
//    Myclass myclass;
//    engine.rootContext()->setContextProperty("myclass", &myclass);
    //在qml加载之前注册c++类
     //qmlRegisterType注册C++类到QML
    //arg1:import时模块名 在qml中使用import QmlTestObject 1.0引入文件,1.0是主版本和次版本号
    //arg2:主版本号
    //arg3:次版本号
    //arg4:QML类型名
    //注册完成后去qml文件去使用
    qmlRegisterType<Myclass>("Myclass",1,0,"Myclass");

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);



    return app.exec();

main.qml调用

cpp 复制代码
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
import     Myclass 1.0
Window {
    id:rootwindow
    visible: true
    width: 640;
    height: 480
    title: qsTr("Hello qt")
    property int myspeed:myclass.value
    signal setspeed(int set_spped)
    signal setqmlspeed(int set_qmlspped)
    Myclass{
        id:myclass
        value: slider.value


    }
            Button {
                        text: "调用c++函数"
                        onClicked: {
                            myclass.function1()
//                            myclass.value=100;
//                            console.log( myclass.value)//value 没有改变
                        }
                  }
}
相关推荐
励志不掉头发的内向程序员6 小时前
【从零写一个CAD 03】三个 double 值得单独一个类吗:把视图变换抽成 View
开发语言·c++·qt·学习·系统架构
蒸蒸yyyyzwd13 小时前
秋招学习笔记 day46
c++·八股
码匠许师傅16 小时前
【C++三方组件】cpp-httplib:一个头文件起 HTTP 服务
开发语言·c++·http
无名猿17 小时前
new/delete 与 malloc/free:为什么绝对不能混用
c++·内存管理·现代c++·踩坑记录
Mr_Mao18 小时前
告别选型困难!集 VueUse、ahooks、Mantine 于一身:286 个 Hook 的 ReaUse 来了
前端·javascript·react.js
2601_9622186119 小时前
C++中decltype关键字的实现
开发语言·c++
默_笙19 小时前
🚙 一条腿走路会摔:ES 关键词检索、混合召回与 ReRank 裁判
前端·javascript
繁华的地方不一定留下你的脚印19 小时前
C++ std::variant 与 std::visit:安全保存多种类型,写清每个处理分支
开发语言·c++
程序员老陆19 小时前
WIN32_LEAN_AND_MEAN:Windows 头文件里的“精简编译开关”
c++·windows
元岳数字人小元20 小时前
数字人源码系统:模块化开发赋能智能场景灵活迭代升级
运维·人工智能·开源·人机交互·交互