Solved Acess engine within function
-
What are you using to get the GPS data ?
-
I used QQmlProperty to read *object
MyClass myClass; QQmlApplicationEngine engine; QQmlEngine engine2; QQmlComponent component(&engine2,QUrl(QStringLiteral("qrc:/MainForm.ui.qml"))); QObject *object = component.create(); // QVariant latitude = QQmlProperty::read(object, "icoordlat"); QVariant longitude = QQmlProperty::read(object, "icoordlon");
-
It looks like you are trying to go back and forth between QML and C++ rather than trying to use the usual channels to communicate between both.
Where are you setting these two values ?
-
Hey I set them in my MainForm.ui.qml. From my research of QML it seemed this was the common way to communicate between C++ and QML. Basically, I am trying to get these qt positioning values over to C++ so that they can be evaluated against a database and then the output presented on the screen. I didn't think it would be this difficult to interface between the two. Any help sending me down the right path would be great.
Mainform.ui.qml
import QtQuick 2.5 import QtPositioning 5.5 import QtLocation 5.5 import QtQuick.Controls 1.4 Rectangle { width: 360 height: 360 property alias item1: item1 property alias toolButton1: toolButton1 property alias src: src property string icoordlat: src.position.coordinate.latitude property string icoordlon: src.position.coordinate.longitude Item { id: item1 PositionSource { id: src updateInterval: 1000 active: true property double icoordlat: src.position.coordinate.latitude property double icoordlon: src.position.coordinate.longitude } } MouseArea { id: mouseArea anchors.rightMargin: 0 anchors.bottomMargin: 0 anchors.leftMargin: 0 anchors.topMargin: 0 anchors.fill: parent Text { id: t1 width: 343 height: 145 font.pointSize: 60 anchors.centerIn: parent text: decile anchors.verticalCenterOffset: 9 anchors.horizontalCenterOffset: 1 } Text { id: t2 width: 343 height: 106 font.pointSize: 44 anchors.centerIn: parent text: postcode anchors.verticalCenterOffset: -119 anchors.horizontalCenterOffset: 1 } Text { id: t3 width: 343 height: 106 font.pointSize: 16 anchors.centerIn: parent text: src.position.coordinate.latitude anchors.verticalCenterOffset: 120 anchors.horizontalCenterOffset: 1 } Text { id: t4 width: 343 height: 106 font.pointSize: 16 anchors.centerIn: parent text: src.position.coordinate.longitude anchors.verticalCenterOffset: 160 anchors.horizontalCenterOffset: 1 } ToolButton { id: toolButton1 width: 233 height: 233 anchors.verticalCenterOffset: 200 text: "Refresh" } } }
This is where I get the function to execute on button push
main.qml
Window { visible: true MainForm { toolButton1.onClicked: { obj.clickedButton(); } anchors.fill: parent } }
-
In your
onClick
handler, you can retrieve the values fromicoordlat
,icoordlon
since they are properties of your Mainform and pass them toclickButton
.
Some thing likeonClicked: { obj.clicked(icoordlat, icoordlon); }
No need to try to go through the engine.
I'd recommend taking a look at the QtQml C++ integration chapter from Qt's documentation.
-
Hi thanks very much for the reply again. I have modified my code and I am able to get the application to compile.
I'm able to pass the long & lat over to C++ and get the result (seen with qDebug) but the qml screen data does not get refreshed with :setDecile(decile);
setPostCode(postCode);main.h
#ifndef MAIN_H #define MAIN_H #include <QObject> #include <QDebug> #include <QQuickItem> #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QDebug> #include <QUrl> #include <QQmlContext> #include <QQmlComponent> #include <QQmlProperty> #include <QSqlDatabase> #include <QtSql> #include <QtPositioning/QGeoCoordinate> #include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkReply> #include <QGeoAddress> #include <QObject> #include <QQuickItem> #include <QQuickView> class MyClass : public QObject { Q_OBJECT Q_PROPERTY(QString decile READ decile WRITE setDecile NOTIFY decileChanged) Q_PROPERTY(QString postCode READ postCode WRITE setPostCode NOTIFY postCodeChanged) QString postCode() const { return _postCode; } QString decile() const { return _decile; } signals: void decileChanged(const QString& decile); void postCodeChanged(const QString& postCode); public slots: void setDecile(const QString& decile) { if (_decile == decile) { return; } _decile = decile; emit decileChanged(decile); } void setPostCode(const QString& postCode) { if (_postCode == postCode) { return; } _postCode = postCode; emit postCodeChanged(postCode); } void update(QString icoordlat, QString icoordlon) { QString dbname = "affluence.sqlite"; QString filePath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); filePath.append( "/"+dbname); QSqlDatabase dbsqlite = QSqlDatabase::addDatabase("QSQLITE","dbsqlite"); dbsqlite.setDatabaseName(filePath); dbsqlite.open(); if (dbsqlite.open()) { QString Qlatitude2 = icoordlat.left(6); QString Qlongitude2 = icoordlon.left(6); QString perc = "%"; Qlatitude2 = Qlatitude2 + perc; Qlongitude2 = Qlongitude2 + perc; qDebug() << "soup: " << Qlatitude2 << Qlongitude2; QSqlQuery querydb(dbsqlite); querydb.prepare("select * FROM affluence WHERE latitude LIKE :Qlatitude AND longitude LIKE :Qlongitude"); querydb.bindValue(":Qlatitude", Qlatitude2); querydb.bindValue(":Qlongitude", Qlongitude2); querydb.exec(); while (querydb.next()) { QString Qlatitude3 = querydb.value(4).toString(); QString Qlongitude3 = querydb.value(5).toString(); QString decile = querydb.value(3).toString(); QString postCode = querydb.value(2).toString(); setDecile(decile); setPostCode(postCode); qDebug() << "latitude: " << Qlatitude3 << " longitude: " << Qlongitude3 << " decile: " << decile << "post code:" << postCode; } } else { qDebug() << "can't connect to sqlite " << dbsqlite.lastError(); } } private: QString _decile; QString _postCode; }; #endif // MAIN_H
main.cpp
int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); MyClass myClass; QQmlApplicationEngine engine; QQmlEngine engine2; QQmlComponent component(&engine2,QUrl(QStringLiteral("qrc:/MainForm.ui.qml"))); QObject *object = component.create(); engine.rootContext()->setContextProperty(QStringLiteral("obj"), &myClass); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
main.qml
import QtQuick 2.5 import QtQuick.Window 2.2 import QtPositioning 5.5 import QtLocation 5.6 import QtPositioning 5.2 Item { Window { visible: true MainForm { toolButton1.onClicked: { obj.update(icoordlat, icoordlon); } anchors.fill: parent } } }
MainForm.ui.qml
import QtQuick 2.5 import QtPositioning 5.5 import QtLocation 5.5 import QtQuick.Controls 1.4 Rectangle { width: 360 height: 360 property alias item1: item1 property alias toolButton1: toolButton1 property alias src: src property string icoordlat: src.position.coordinate.latitude property string icoordlon: src.position.coordinate.longitude Item { id: item1 PositionSource { id: src updateInterval: 1000 active: true property double icoordlat: src.position.coordinate.latitude property double icoordlon: src.position.coordinate.longitude } } MouseArea { id: mouseArea anchors.rightMargin: 0 anchors.bottomMargin: 0 anchors.leftMargin: 0 anchors.topMargin: 0 anchors.fill: parent Text { id: t1 width: 343 height: 145 font.pointSize: 60 anchors.centerIn: parent text: decile anchors.verticalCenterOffset: 9 anchors.horizontalCenterOffset: 1 } Text { id: t2 width: 343 height: 106 font.pointSize: 44 anchors.centerIn: parent text: postcode anchors.verticalCenterOffset: -119 anchors.horizontalCenterOffset: 1 } Text { id: t3 width: 343 height: 106 font.pointSize: 16 anchors.centerIn: parent text: src.position.coordinate.latitude anchors.verticalCenterOffset: 120 anchors.horizontalCenterOffset: 1 } Text { id: t4 width: 343 height: 106 font.pointSize: 16 anchors.centerIn: parent text: src.position.coordinate.longitude anchors.verticalCenterOffset: 160 anchors.horizontalCenterOffset: 1 } ToolButton { id: toolButton1 width: 233 height: 233 anchors.verticalCenterOffset: 200 text: "Refresh" } } }
-
I may have missed it but I don't see any use of
obj
properties in your code. -
when I used the "go to slot" option on the button it created the function inside main.qml so I just went with that
main.qml
import QtQuick 2.5 import QtQuick.Window 2.2 import QtPositioning 5.5 import QtLocation 5.6 import QtPositioning 5.2 Item { Window { visible: true MainForm { toolButton1.onClicked: { obj.update(icoordlat, icoordlon); } anchors.fill: parent } } }
and obj is set inside main.cpp
int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); MyClass myClass; QQmlApplicationEngine engine; QQmlEngine engine2; QQmlComponent component(&engine2,QUrl(QStringLiteral("qrc:/MainForm.ui.qml"))); QObject *object = component.create(); engine.rootContext()->setContextProperty(QStringLiteral("obj"), &myClass); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
-
for anybody with the same questions I managed to get it working by adding a connection in the QML
Connections { id: conn2 target: obj ignoreUnknownSignals: true onPostCodeChanged: { t2.text = postCode } }
Thanks SGaist !
-
AFAIK, you shouldn't need that:
Text { id: t2 text: obj.postCode }
should do what you want automatically through the binding.