Я начал учиться QML
недавно (после того, как попробовал это давным-давно), и я застрял в пути Qt
C++
код взаимодействует с QML
и наоборот.
у меня есть Counter
который имеет следующий заголовок:
#include <QObject>
#include <QTimer>
class Counter : public QObject
{
Q_OBJECT
Q_PROPERTY(int count
READ getCount
WRITE setCount
NOTIFY signalCountChanged)
public:
Counter(QObject *parent = Q_NULLPTR);
int getCount();
void setCount(int count);
signals:
void signalCountChanged(int);
public slots:
void slotStart();
private slots:
void slotTimeout();
private:
int count;
QTimer *timer;
};
мой main.cpp
как следует:
#include <QtGui/QGuiApplication>
#include <QtQml/QQmlContext>
#include <QtGui/QGuiApplication>
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickView>
#include "counter.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<Counter>("org.qmlplayground.counter", 0, 1, "Counter");
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *viewO = dynamic_cast<QObject*>(view.rootObject());
Counter c;
// Register Counter instance as "counter" property of top level context so that it can be accessed from within the QML code (for example: set the value count)
view.rootContext()->setContextProperty("counter", &c);
QObject::connect(viewO, SIGNAL(signalStartCounter()),
&c, SLOT(slotStart()));
QObject::connect(viewO, SIGNAL(signalQuit()), &app, SLOT(quit()));
view.show();
return app.exec();
}
и наконец часть моего QML
( main.qml
который загружен в QQuickView
в то время как остальные являются формой пользовательского интерфейса):
import QtQuick 2.7
import QtQuick.Window 2.2
// Importing some JavaScript files
import "qrc:/loggingFunctions.js" as LOG
import "qrc:/parseFunctions.js" as PARSE
// Importing a Qt C++ custom module
import org.qmlplayground.counter 0.1
MainForm {
property int countState: counter.count // ERROR HERE
signal signalStartCounter()
signal signalQuit()
anchors.fill: parent
textInputMouseArea.onClicked: {
LOG.logger("Clicked! Selecting all text in text input field", "N")
textInput.selectAll()
}
textInput.onAccepted: {
if(textInput.text === "quit") signalQuit()//Qt.quit();
if(textInput.text === "help") textInput.text = LOG.logger("Displaying help", "H");
var res = PARSE.parseInput(textInput.text);
if(res && (typeof res === 'object') && res.constructor === Array) {
switch(res[0]) {
case "fact":
labelOutput.text = res[1];
break;
case "count":
counter.count = res[1];
signalStartCounter();
break;
}
}
}
onCountStateChanged:
console.log("Hello")
textInput.onTextChanged:
console.log("Text changed");
}
Как вы можете видеть, я уже проверил два сигнала от моего QML
к моему C++
код один подключен к моему QGuiApplication
слот quit()
а другой связан с моим counter
слот slotStart()
, Работает нормально. Кажется, что линия
counter.count = res[1];
не вызывает никаких проблем (возможно, потому что это JS
и не QML
?). Теперь я хочу прочитать count
ценность моего Counter
экземпляр и обновить мой пользовательский интерфейс соответственно. Если я не ошибаюсь каждый QML
свойство автоматически получает пару вещей, одна из которых является onChanged
метод (обработчик события или как он там называется).
Когда я запускаю свой код, я получаю
`qrc:/main.qml:21: ReferenceError: counter is not defined
Я думал что делаю view->rootContext()->setContextProperty("counter", &c);
было бы достаточно, но кажется, что я что-то упустил. Таким образом, более общий вопрос будет, как мне должным образом делать C++
объект виден в QML
контекст.
Мне потребовалось около 2 часов, чтобы понять (я разместил свой вопрос, когда я был на грани совершения самоубийства: D), но ответ был действительно очевиден: как я могу вызвать свойство, которое еще не было инициализировано? Решение моей проблемы в основном состоит в setContextProperty()
ДО Я загружаю QML
файл:
// ...
QQuickView view;
Counter c;
view.rootContext()->setContextProperty("counter", &c);
view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
// ...
Таким образом, свойство сначала добавляется в корневой контекст view
и после этого дополнительный QML
материал загружен но counter
собственность все еще присутствует). С предыдущей версией моего кода я в основном пытался получить доступ counter
внутри моего QML
файл ДО Я добавил это как собственность.
Других решений пока нет …