在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 沒有改變}}
}
?