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 没有改变
                        }
                  }
}
相关推荐
疯狂的沙粒3 分钟前
uniapp开发企业微信小程序时 wx.qy.login 在uniapp中使用的时候,需要导包吗?
前端·javascript·微信小程序·小程序·uni-app
小张快跑。28 分钟前
<el-date-picker>配置禁用指定日期之前的时间选择(Vue2+Vue3)
前端·javascript·vue.js
wujj_whut35 分钟前
【PC网上邻居--1】基于Samba协议的局域网文件共享系统设计与实现
c++
想睡hhh37 分钟前
Practice 2025.5.29 —— 二叉树进阶面试题(1)
c++·算法
geovindu44 分钟前
vue3: tmap (腾讯地图)using typescript
前端·javascript·typescript
Ashlee_code1 小时前
TRS收益互换平台开发实践:从需求分析到系统实现
java·数据结构·c++·python·架构·php·需求分析
小王努力学编程1 小时前
【Linux网络编程】传输层协议TCP,UDP
linux·网络·c++·udp·tcp
kooboo china.2 小时前
Tailwind CSS 实战,基于 Kooboo 构建 AI 对话框页面(四):语音识别输入功能
前端·css·人工智能·ui·html·交互·语音识别
Python涛哥2 小时前
前端流行框架Vue3教程:26. 异步组件
前端·javascript·vue.js
代码搬运媛2 小时前
Next.js路由导航完全指南
前端·javascript·vue.js·next