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 没有改变
                        }
                  }
}
相关推荐
TiAmo zhang22 分钟前
人机融合智能 | 人智交互中的机器行为设计与管理
人机交互·交互
拉不动的猪1 小时前
pc和移动页面切换的两种基本方案对比
前端·javascript·vue.js
Hilaku1 小时前
前端日志调试也能专业化?我们这样设计日志系统
前端·javascript
十年编程老舅1 小时前
C/C++ 高频八股文面试题1000题(一)
c++·八股文·大厂面试题·c++八股文·八股文面试题·c++面经
BUG收容所所长2 小时前
深入理解 AJAX,从 XMLHttpRequest 到现代 Fetch API
前端·javascript·ajax
Sun_light2 小时前
「一文看懂 JS 深浅拷贝,彻底告别面试踩坑!」
前端·javascript
YG9082 小时前
微信小程序页面传参乱码问题如何解决?
前端·javascript
Hilaku2 小时前
前端权限系统怎么做才不会写吐?我们项目踩过的 3 套失败方案总结
前端·javascript·vue.js
nbsaas-boot2 小时前
Vue 组件数据流与状态控制最佳实践规范
前端·javascript·vue.js
鹏多多.3 小时前
详解vue渲染函数render的使用
前端·javascript·vue.js·前端框架