在QML中可以有条件地访问QObject子类的函数。这些条件是:
- 使用Q_INVOKABLE宏标记的public函数
- public槽函数
现在我们来实现这两种函数,然后在QML中调用。
#ifndef MYVIEWMODEL_H
#define MYVIEWMODEL_H
#include <QObject>
class MyViewModel : public QObject
{
Q_OBJECT
explicit MyViewModel(QObject *parent = nullptr);
Q_INVOKABLE bool onClicked(QString args);
public slots:
void refresh();
};
#endif // MYVIEWMODEL_H
上述代码中,主要有两个函数:
- onClicked函数,被Q_INVOKABLE宏标记了,并且有参数和返回值。
- 一个public槽函数,没有参数和返回值。
源文件如下:
#include <stdio.h>
#include "MyViewModel.h"
#include "qdebug.h"
MyViewModel::MyViewModel(QObject *parent)
: QObject{parent}
{
}
bool MyViewModel::onClicked(QString args)
{
qDebug()<<"onClicked's args:"<<args;
return true;
}
void MyViewModel::refresh()
{
qDebug()<<"refresh";
}
在main函数中我们加数据传递给QML中:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "MyViewModel.h"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
MyViewModel viewModel();
QQmlApplicationEngine engine;
QQmlContext* context=engine.rootContext();
context->setContextProperty("viewModel",QVariant::fromValue(&viewModel));
const QUrl url(QStringLiteral("qrc:/main.qml"));
engine.load(url);
return app.exec();
}
然后在QML中使用:
Button {
text: qsTr("button")
onClicked: {
var ret = viewModel.onClicked(text)
console.log("onClicked ret=" + ret)
viewModel.refresh()
}
}
我们在onClicked
事件中直接调用。但是槽函数其实也可以带参数和返回值的。