У меня есть три класса, созданные на С++ как Window, PropertyList и MyParams, и я хочу передать эти два класса PropertyList и MyParams в qml.
class Window
{
public:
PropertyList* getPropertyList();
private:
PropertyList* propertyList;
};
class PropertyList : public QObject
{
Q_OBJECT
public:
MyParams* getMyParams();
Q_INVOKABLE void test();
private:
MyParams* myParams;
};
class MyParams : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE void test();
};
int main(int argc, char *argv[])
{
Window* window = new Window();
PropertyList* propertyList = window->getPropertyList();
MyParams* myParam = propertyList->getMyParams();
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty(QStringLiteral("myParams"), myParam);
engine.rootContext()->setContextProperty(QStringLiteral("propertyList"), propertyList);
}
Почему это работает:
engine.rootContext()->setContextProperty(QStringLiteral("propertyList"), propertyList);
И это не удается:
engine.rootContext()->setContextProperty(QStringLiteral("myParams"), myParam);
Это потому, что я объявляю PropertyList как Q_OBJECT? И как я могу это исправить? Большое спасибо.
propertyList.test() может быть вызван успешно, в то время как myParams.test() не может быть вызван и привел к сбою qml.
@Hubi да, я поставил Q_OBJECT в определение класса
Как это не удается? Вы получаете ошибку времени выполнения?
@user6556709 user6556709 ах, я добавлю больше кода, чтобы показать, как это терпит неудачу
QML обычно не дает сбоев без ошибки времени выполнения, и ваше описание не соответствует коду. Оба реализованы как QObjects, и это необходимо для обоих. У вас не может быть Q_INVOKABLE, если это не QObject. Вы можете сделать их свойствами без, но вам нужно зарегистрировать типы.
@user6556709 user6556709 что вы имеете в виду под этим нужно для обоих. Я объявляю MyParams и PropertyList как Q_OBJECT
Этот пример не будет компилироваться. Обратите внимание: stackoverflow.com/help/репрекс
Я не вижу никаких проблем в вашем примере кода, потому что он неполный (считайте: https://stackoverflow.com/help/репрекс).
Тем не менее я реализовал решение для вас. Надеюсь, это поможет. (Предупреждение: вокруг класса Window
будут утечки памяти, но это должно помочь понять привязку C++ и Qml)
Вот ваш PropertyList.h
:
#ifndef PROPERTYLIST_H
#define PROPERTYLIST_H
#include "myparams.h"
#include <QObject>
class PropertyList : public QObject
{
Q_OBJECT
public:
explicit PropertyList(QObject *parent = nullptr) : QObject (parent) { }
MyParams* getMyParams()
{
return myParams;
}
Q_INVOKABLE void test()
{
qDebug() << "PropertyList test";
}
private:
MyParams* myParams = new MyParams();
};
#endif // PROPERTYLIST_H
Вот ваш MyParams.h
:
#ifndef MYPARAMS_H
#define MYPARAMS_H
#include <QObject>
#include <QDebug>
class MyParams : public QObject
{
Q_OBJECT
public:
explicit MyParams(QObject *parent = nullptr) : QObject (parent) { }
Q_INVOKABLE void test()
{
qDebug() << "MyParams test";
}
};
#endif // MYPARAMS_H
Вот ваш main.cpp
:
#include "propertylist.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include <QQmlContext>
#include <QDebug>
class Window
{
public:
PropertyList* getPropertyList()
{
return propertyList;
}
private:
PropertyList* propertyList = new PropertyList(nullptr);
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
Window* window = new Window();
PropertyList* propertyList = window->getPropertyList();
MyParams* myParam = propertyList->getMyParams();
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty(QStringLiteral("myParams"), myParam);
engine.rootContext()->setContextProperty(QStringLiteral("propertyList"), propertyList);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
{
return -1;
}
return app.exec();
}
Вот ваш main.qml
:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
anchors.centerIn: parent
Button {
text: "myParams"
onClicked: {
myParams.test()
}
}
Button {
text: "propertyList"
onClicked: {
propertyList.test()
}
}
}
}
Спасибо, я нашел свою проблему, забыл инициализировать объект myParam :)), сбил меня с толку.
Рад помочь вам. Пожалуйста, установите этот ответ как «правильный ответ» и проголосуйте за него ;-). Так что вы тоже можете помочь другим.
Пожалуйста, покажите нам
MyParams
. Это QObject?