QML与C++交互2

发布于:2025-05-26 ⋅ 阅读:(59) ⋅ 点赞:(0)

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

在C++中调用QML的方法

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

示例

//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;
}
}
}
//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

#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

#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中注册类

#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调用 

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 没有改变
                        }
                  }
}

 


网站公告

今日签到

点亮在社区的每一天
去签到