[SOLVED] Custom NonSattelite PositionSource
-
Yes you can. But as I said, you then have to implement the source yourself. Where are you getting the non-satellite data from?
-
Hi Conny, not sure I quite understand what you mean by implement source?
Current plan is:
- take source code snippet from this example http://developer.qt.nokia.com/wiki/Retrieve_Location_Using_Qt_Mobility
- find the way how to expose to QML the location data (latitude, longitude)
SO eventually I should have longitude and latitude data available with updates in QML from non-sat source, isn't it?:)
-
Hmm, I had implemented the Qt C++ code from the examples, I learned a bit on how to expose Qt C++ data to QML, but seems I am not quite there to do it properly...
The code in C++ actually "loads" data into m_pLabel (below)
@QGeoCoordinate geoCoordinate = geoPositionInfo.coordinate();
qreal latitude = geoCoordinate.latitude();
qreal longitude = geoCoordinate.longitude();m_pLabel->setText( QString("Latitude: %1 \n Longitude: %2").arg(latitude).arg(longitude) );@
But how can I refer to this text in C++ to get it passed as ContextProperty to QML??
@QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationLockPortrait);
viewer.rootContext()->setContextProperty("currentDateTime",m_pLabel.text );@What should be there in the code instead of m_pLabel.text?
I know I am naive trying to apply QML approach;) Please help!
-
A QObject subclass instance exposing the text via a property with a proper notify signal :P
-
Hmm what do you mean?
Sorry I only started C++ "induction" :(I got the idea - I need to set a NOTIFY property and signal for an object.
But what would be the best solution here - to create a new QObject, somehow pass to it the location data from the m_pLabel and then expose to QML??[EDIT: fixed smiley that made "induction" a link :-), Volker]
-
You don't need the label at all.
Write your own QObject subclass, expose a QString(if you want the data to be exposed as text) property with READ and NOTIFY. And make sure to emit your NOTIFY signal whenever the value changes.
Just create an instance of your class and expose to QML as a context property.
"Exchanging data between QML and C++":http://developer.qt.nokia.com/doc/qt-4.7/qtbinding.html#id-1b3a8b62-0fb5-44c3-b68b-ee1cbf29d0c3
-
Thanks a lot;) !
I will try to post my code hereto for the others and put SOLVED afterwards
-
Kkrzewniak, many thanks for your help, could you please validate the code a bit (I guess I am still missing the part with emiting signal and also seems like I haven't yet added important chunk of the code to the CPP file...
Header:
@class NonSatCoordsSource : public QObject
{
Q_OBJECT
Q_PROPERTY (QString text READ text WRITE setText NOTIFY textChanged)
public:
void positionUpdated(QGeoPositionInfo geoPositionInfo);
private:
void startLocationAPI();
QGeoPositionInfoSource* m_pLocationInfo;
QString* m_pString;
signals:
void textChanged();
};@I declared the class and made one property there which could be read/written and notified.
I also declared the functions (at least I hope I did it correctly)Now in CPP part I need to expose the class and describe these functions as I get it:
@NonSatCoordsSource::NonSatCoordsSource(QObject *parent) : m_pLocationInfo(NULL), m_pString(NULL)
NonSatCoordsSource::~NonSatCoordsSource()
{}
void NonSatCoordsSource::startLocationAPI()
{
if (!m_pLocationInfo)
{
m_pLocationInfo =
QGeoPositionInfoSource::createDefaultSource(this);
m_pLocationInfo->setPreferredPositioningMethods(QGeoPositionInfoSource::NonSatellitePositioningMethods);
connect(m_pLocationInfo, SIGNAL(positionUpdated(QGeoPositionInfo)),
this, SLOT(positionUpdated(QGeoPositionInfo)));
m_pLocationInfo->startUpdates();
}
}void NonSatCoordsSource::positionUpdated(QGeoPositionInfo geoPositionInfo)
{
if (geoPositionInfo.isValid())
{
QGeoCoordinate geoCoordinate = geoPositionInfo.coordinate();
qreal latitude = geoCoordinate.latitude();
qreal longitude = geoCoordinate.longitude();
m_pString->setText( QString("Lat: %1 Long: %2").arg(latitude).arg(longitude) );
}
}@This is where I stuck basically for now just reading C++ for dummies further...But feels like I am close enough?:)
-
Here is the solution and final "code" (sorry if it is not high class code though as I only started to learn Qt). So basically I am able to turn it on off using nonsatdata.enable(), I can "read" the coordinates from within QML via nonsatdata.lat and nonsatdata.lon...
The problem I have below is that the signals are not working/firing off (onLatChanged and onLonChanged ) ;(
I kind of feel what the problem is but can't fix it...so any help is very appreciated!- Qml:
@import NonSatLocation 1.0
...
NonSatLocation { // defined in nonsat.cpp & h, exposed to qml as a type
id: nonsatdata
onLatChanged: { console.log("signal nonsatdata.lat")}
onLonChanged: { console.log("signal nonsatdata.lon")}
}
@- main.cpp:
@...
qmlRegisterType<NonSatLocation> ("NonSatLocation", 1,0, "NonSatLocation");
...@- nonsat.h:
@class NonSatLocation : public QObject
{
Q_OBJECT
Q_PROPERTY (double lat READ lat WRITE setLat NOTIFY latChanged)
Q_PROPERTY (double lon READ lon WRITE setLon NOTIFY lonChanged)
public:
NonSatLocation (QObject *parent = 0);
double lat () const {return m_lat;}
double lon () const {return m_lon;}
void setLat (double &lat)
{
m_lat = lat;
emit latChanged();
}
void setLon (double &lon)
{
m_lon = lon;
emit lonChanged();
}Q_INVOKABLE void enable(); Q_INVOKABLE void disable();
signals:
void latChanged();
void lonChanged();private slots:
void positionUpdated(const QGeoPositionInfo &info);private:
double m_lat;
double m_lon;
QGeoPositionInfoSource *source;
};@- nonsat.cpp:
@NonSatLocation::NonSatLocation (QObject *parent)
: QObject (parent)
{
source = QGeoPositionInfoSource::createDefaultSource(this);
if (source) {
source->setUpdateInterval(3000); // time in milliseconds
source->setPreferredPositioningMethods(QGeoPositionInfoSource::NonSatellitePositioningMethods);
}
}void NonSatLocation::enable()
{
if (source) {
connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
this, SLOT(positionUpdated(QGeoPositionInfo)));
source->startUpdates();
}
}
void NonSatLocation::disable()
{
if (source) {
source->stopUpdates();
disconnect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
this, SLOT(positionUpdated(QGeoPositionInfo)));
}
}
void NonSatLocation::positionUpdated(const QGeoPositionInfo &info)
{
if (info.isValid()) {qDebug() << info.coordinate(); QGeoCoordinate geoCoordinate = info.coordinate(); double latitude = geoCoordinate.latitude(); double longitude = geoCoordinate.longitude(); m_lat = latitude; m_lon = longitude; }
}@
-
Yes you are missing one more think:
instead of:
@m_lat = latitude;
m_lon = longitude;@
you should use your methods that call signals i.e :
@setLat(latitude);
setLon(longitude);@
And that's it, it works !!!
By the way thanks for sharing your code :)