QML与C++交互2
在QML与C++的交互中,主要有两种方式:在C++中调用QML的方法和在QML中调用C++的方法。以下是具体的实现方法。
在C++中调用QML的方法
首先,我们需要在QML文件中定义一个函数,然后在C++代码中调用它。
示例
//QML main.qml文件
import QtQuick 2.12
import QtQuick.Window 2.12Window {
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_OBJECTQ_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:rootwindowvisible: truewidth: 640;height: 480title: qsTr("Hello qt")property int myspeed:myclass.valuesignal setspeed(int set_spped)signal setqmlspeed(int set_qmlspped)Myclass{id:myclassvalue: slider.value}Button {text: "调用c++函数"onClicked: {myclass.function1()
// myclass.value=100;
// console.log( myclass.value)//value 没有改变}}
}