QGeoCodingManager gives no errors but no results - c++

I am trying to get a QGeoLocation. My version of Qt is 5.7.1, btw, and I am running it on Debian.
I saw this post how to get latitude/longitude from one geo address using Qt c++ on windows?
I copied and pasted the working solution from Scheff's answer, but still got not error and 0 locations. Does this have to do with my setup/environment?
This shorter code has the same effect:
#include <QApplication>
#include <QGeoAddress>
#include <QGeoCodingManager>
#include <QGeoCoordinate>
#include <QGeoLocation>
#include <QGeoServiceProvider>
#include <QtDebug>
int main( int argc, char **argv)
{
QCoreApplication app( argc, argv );
QGeoServiceProvider geoSrv( "osm" );
QGeoCodingManager *geoCoder = geoSrv.geocodingManager();
QGeoAddress addr;
addr.setCountry( "China" );
QGeoCodeReply *geoCode = geoCoder->geocode( addr );
if ( geoCode->error() )
qDebug() << "error";
qDebug() << geoCode->locations().length();
return app.exec();
}

I found your post while struggling with the same problem. For me the QGeoServiceProvider code suddenly stopped working with OpenStreetmap. I quickly tried out the "here" api and that seems to work with exactly the same code. With some quick inspection with wireshark I found the problem easily.
QGeoServiceProvider tries to connect to the OpenStreetMap api at this url: http://nominatim.openstreetmap.org where it gets a redirected via a HTTP 303 to https://nominatim.openstreetmap.org. Apparently, the QGeoServiceProvider isn't able to handle this redirection correctly. I fixed it by providing the new url in the osm.geocoding.host parameter. Using your code this would look like this:
#include <QApplication>
#include <QGeoAddress>
#include <QGeoCodingManager>
#include <QGeoCoordinate>
#include <QGeoLocation>
#include <QGeoServiceProvider>
#include <QtDebug>
int main( int argc, char **argv)
{
QCoreApplication app( argc, argv );
//Add this
QMap<QString,QVariant> params;
params["osm.geocoding.host"] = "https://nominatim.openstreetmap.org";
QGeoServiceProvider geoSrv( "osm", params );
QGeoCodingManager *geoCoder = geoSrv.geocodingManager();
QGeoAddress addr;
addr.setCountry( "China" );
QGeoCodeReply *geoCode = geoCoder->geocode( addr );
if ( geoCode->error() )
qDebug() << "error";
qDebug() << geoCode->locations().length();
return app.exec();
}
Hope this helps!

Instead of using
QGeoServiceProvider geoSrv( "osm", params );
QGeoCodingManager *geoCoder = geoSrv.geocodingManager();
If you use a pointer instead:
QGeoServiceProvider* geoSrv = new QGeoServiceProvider( "osm", params );
QGeoCodingManager *geoCoder = geoSrv->geocodingManager();
It should work(did for me at least)

Related

How to list /dev/sda usb storages mounted with a combobox

I'm looking for the way to show up usb storage path when they are plugged in, the path must be shown in a combobox (in a gui that I'm designing with qt creator (qt 5.9)). I have been searching how to do it but I have not found anything. What I want it's something like:
https://catenarios2.files.wordpress.com/2012/11/002.jpg
Could you please help me to carry on my project? I would be very grateful if you provide an example.
Thank you a lot
The basic idea is the same -- you launch Linux tool via QProcess and parse the result. Here is a simple sketch:
#include <QCoreApplication>
#include <QProcess>
#include <QDebug>
#include <usb.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QProcess devList;
devList.start("lsblk", QStringList() << "-o" << "KNAME");
if (!devList.waitForStarted())
return false;
if (!devList.waitForFinished())
return false;
QString result = QString(devList.readAll());
qDebug() << result;
return a.exec();
}
You can use any other siutable command (quite easy to find them) and should improve parsing, of course, but generally it's all the same.
AFAIK, mount points could be obtained from /proc/mounts with something like...
#include <QCoreApplication>
#include <mntent.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
struct mntent *ent;
FILE *aFile;
aFile = setmntent("/proc/mounts", "r");
if (aFile == NULL) {
perror("setmntent");
exit(1);
}
while (NULL != (ent = getmntent(aFile))) {
printf("%s %s\n", ent->mnt_fsname, ent->mnt_dir);
}
endmntent(aFile);
return a.exec();
}
Better than cat launching or someting else, also taken from some snippet and should be improved.
And, finally, in case you'll need USD device info, it could be something like...
#include <QCoreApplication>
#include <usb.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
struct usb_bus *bus;
struct usb_device *dev;
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_busses; bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
printf("Trying device %s/%s\n", bus->dirname, dev->filename);
printf("\tID_VENDOR = 0x%04x\n", dev->descriptor.idVendor);
printf("\tID_PRODUCT = 0x%04x\n", dev->descriptor.idProduct);
}
}
return a.exec();
}
This needs sudo apt-get libusb-dev + compiling with -lusb.
Not really much of Qt in the problem and more fundamental "coding" solutions possible, but hopefully that'll give you a push towards appropriate solution.

QTextObjectInterface with Qml TextEdit (QQuickTextEdit)

I registred handler for simple QTextObjectInterface, that draws just 10x10 red rectangle.
When i used QTextEdit in normal QWidget app, it worked.
When i used QQuickTextEdit (TextEdit qml component) in Qt Quick app, it doesn't worked (nothing is drawed, but the rectangle in TextEdit is reserved, because when i change cursor position, i notice that there is something, but just empty space, nothing is drawed.
The QTextObjectInterface intrinsicSize method is called (that explains why i see there is empty space 10x10), but the drawObject method isn't.
I did some research and i found that actually the problem is probably here:
QQuickTextEdit.cpp from Qt 5.3.0 sources (line 1821)
QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) {
.
.
.
if (textFrame->firstPosition() > textFrame->lastPosition()
&& textFrame->frameFormat().position() != QTextFrameFormat::InFlow) {
updateNodeTransform(node, d->document->documentLayout()->frameBoundingRect(textFrame).topLeft());
const int pos = textFrame->firstPosition() - 1;
ProtectedLayoutAccessor *a = static_cast<ProtectedLayoutAccessor *>(d->document->documentLayout());
QTextCharFormat format = a->formatAccessor(pos);
QTextBlock block = textFrame->firstCursorPosition().block();
node->m_engine->setCurrentLine(block.layout()->lineForTextPosition(pos - block.position()));
node->m_engine->addTextObject(QPointF(0, 0), format, QQuickTextNodeEngine::Unselected, d->document,
pos, textFrame->frameFormat().position());
nodeStart = pos;
}
it never reaches the point where node->m_engine->addTextObject is called.
It is because
this part of if condition textFrame->firstPosition() > textFrame->lastPosition() is evaluated to false.
I tried std::cout the firstPostion and the lastPosition when i established the context and firstPosition is 0, lastPosition is 1.
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTextDocument>
#include <QQuickTextDocument>
#include <iostream>
#include <QTextCursor>
#include <QTextBlock>
#include <QPainter>
#include <QAbstractTextDocumentLayout>
#include <QTextCharFormat>
#include "qmlcomponentspace.h"
#include <QTextEdit>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QTextDocument * doc = engine.rootObjects().first()->findChild<QObject *>("editor")->property("textDocument").value<QQuickTextDocument *>()->textDocument();
QTextCursor cur(doc);
int objectType = QTextFormat::UserObject + 1000;
QmlComponentSpace * component = new QmlComponentSpace();
doc->documentLayout()->registerHandler(objectType, component);
QTextCharFormat fmt;
fmt.setObjectType(objectType);
fmt.setForeground(Qt::red);
fmt.setBackground(Qt::red);
cur.movePosition(QTextCursor::End);
cur.insertText(QString(QChar::ObjectReplacementCharacter), fmt);
std::cout << "FIRST:" << doc->rootFrame()->firstPosition() << std::endl;
std::cout << "END:" << doc->rootFrame()->lastPosition() << std::endl;
return app.exec();
}
What i am missing?
The documentation says at
http://doc.qt.io/qt-5/qquicktextdocument.html#details
Warning: The QTextDocument provided is used internally by Qt Quick elements to provide text manipulation primitives. You are not allowed to perform any modification of the internal state of the QTextDocument. If you do, the element in question may stop functioning or crash.

Qt 5 QPrinterInfo::availablePrinters() not listing printers dynamically

I am updating the printer list using availablePrinters(). But it fails to list the new printer added while running application. It is working fine with Qt 4.
The code can be seen below:
#include <QCoreApplication>
#include <QtPrintSupport/QPrinterInfo>
#include <QThread>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
while (1) {
QThread::msleep(3000);
qDebug()<<"List of printers";
QList<QPrinterInfo> printerList=QPrinterInfo::availablePrinters();
foreach (QPrinterInfo printerInfo, printerList) {
qDebug()<<printerInfo.printerName();
}
}
return a.exec();
}
That was a bug with the existing Qt version, and It got fixed on the next version

FLTK draw pixmap gives segfault

I'm trying to draw a xpm file in a C++ program with FLTK.
Here's the code
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include "image.xpm"
#include <FL/Fl_Pixmap.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Image.H>
int main(int argc, char ** argv)
{
Fl_Window *window = new Fl_Window(800,650);
Fl_Pixmap pix(XFACE);
pix.draw(200,200);
window->end();
window->show(argc,argv);
return Fl::run();
}
XFACE is a valid xpm object inside "image.xpm"
But I'm getting a segmentation fault at the pix.draw() line.
What causes this?
/* Try this - this works for me, and I guess is what you meant! */
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Pixmap.H>
#include "image.xpm"
int main(int argc, char ** argv)
{
Fl_Window *window = new Fl_Window(800,650);
Fl_Box *image_box = new Fl_Box(5, 5, 790, 640);
Fl_Pixmap pix(XFACE);
window->end();
image_box->image(pix);
window->show(argc,argv);
return Fl::run();
}
/* end of file */
To be honest, that doesn't even look like valid fltk code; you are calling the draw() method directly, and AFAIK that is seldom valid in fltk.
You probably want to ask over on their mailing list - they are pretty responsive.
Also, did you look at the pixmap demo in the "test" folder of the tarball - see what it does, then copy it!

How to print unicode characters using Qt?

I'm trying to do something very simple, I just want to print my native language, pt-br in Windows Console.
IDE Creator
I created a new project->other->Qt Console Application the I put it in my main.cpp file:
#include <QCoreApplication>
#include <QDebug>
#include <QTextCodec>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "aeiou áéíóú";
std::cout << "aeiou áéíóú" << endl;
return 0;
}
here is what I got:
C:\Users\maiko.costa\testeQtConsole\debug>testeQtConsole.exe
aeiou ßÚݾ·
aeiou ßÚݾ·
C:\Users\maiko.costa\testeQtConsole\debug>
I've tried it too, but with the same previous output:
#include <QCoreApplication>
#include <QDebug>
#include <QTextCodec>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTextCodec *codec = QTextCodec::codecForName("CP1252");
QTextCodec::setCodecForCStrings(codec);
qDebug() << "aeiou áéíóú";
std::cout << "aeiou áéíóú" << endl;
return 0;
}
The System encode for Windows 7 is it right ?
what am I missing ?
I am not that familiar with QT but I think this can help you just as well. The Windows console uses the OEM char set. Therefore, in order to properly print characters on std::cout they need to be encoded using OEM. This can be accomplished using the Windows API CharToOem.
Small example, just so you get the idea (here input is assumed to be UTF16):
void oemPrint(const wchar_t* str) {
char* chars = (char*)alloca(strlen(str)+1);
CharToOemW(str, chars);
fputs(chars, stdout);
}
// Usage:
oemPrint(L"aeiou áéíóú");
EDIT: A QT solution might be to use QTextCodec::codecForName("IBM 850") - this is the OEM codec.
I find the solution in this thread. Output unicode strings in Windows console app
If I ran chcp 65001 in windows console before I ran my app the characters are printed correctly.
I don't know how to workaround it in my source code, then I call this program manually with the start cpp function.
Here is the return line of function I wrote that displays passwords as ● ● ● ● ●
return QString::fromUtf8( "\u25CF \u25CF \u25CF \u25CF \u25CF" );
QString::fromUnicode should work the same.
Maybe something like:
QString x = QString::fromUtf8( "\u25CF \u25CF \u25CF \u25CF \u25CF" );
std::cout << qPrintable(x) << std::endl;
Of course change it to QString::fromUnicode... hope this helps
QString a="aeiou áéíóú";
std::cout<< a.toStdString().data();