QUrl doesn't work with parts from text file (Qt c++) - c++

I want to make an url with some parts extracted from a text file.
I have the following code:
crack_order = new QFile("orders.txt"); //I have QFile *crack_order in headers
crack_order->open(QIODevice::ReadOnly);
while(!crack_order->atEnd()){
QStringList orders;
orders = QString(crack_order->readAll()).split('\n',QString::SkipEmptyParts);
foreach (QString order, orders){
ui->debugtextbox->setText(order); //until here, it works fine!
url = "http://www.example.com/customers/orders/"+order+"/another/thing.txt";
it does not work, the url request doesn't performed correctly. HOWEVER, if I put the following variable:
"QString order = "12233";
before "url", it works!
Then, I guess the problem is that it's getting the "order" from a text file, and QUrl doesn't like it.
Any idea?
Thanks in advanced.

Related

How to solve the error FODC0002 when using QXmlFormatter?

I'm trying to use QXmlQuery to get some elements from a XML file. Everything works fine (I'm able to validate the source XML file and etc) until I get to the part in which I try to use QXmlFormatter, in order to write the results to another XML file. When I get to this part, the following error is shown: Error FODC0002 in tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:inputDocument, at line 1, column 0: Premature end of document.
The code is based on the "Recipes" project available as an example in Qt. The only difference here is that I made a simpler version of the "cookbook" XML file. I've tried to use QBuffer(the approach implemented in the example) instead of a file, but as expected, got the same result.
Here is the source XML, called temp2_xml.xml
<?xml version="1.0" encoding="UTF-8"?>
<cookbook>
<recipe>
<title>Quick and Easy Mushroom Soup</title>
<title>Cheese on Toast</title>
</recipe>
</cookbook>
Here is the Xquery file, called allRecipes.xq:
(: Select all recipes. :)
declare variable $inputDocument external;
doc($inputDocument)/cookbook/recipe/<p>{string(title)}</p>
And here's the code:
QFile aqr_xq("C:/test_xml/allRecipes.xq");
aqr_xq.open(QIODevice::ReadOnly);
QFile file("C:/test_xml/temp_xml.xml");
file.open(QIODevice::ReadWrite);
QFile aqr_r;
aqr_r.setFileName("C:/test_xml/temp2_xml.xml");
aqr_r.open(QIODevice::ReadOnly);
QTextStream in(&aqr_r);
QString inputDocument = in.readAll();
const QString str_query(QString::fromLatin1(aqr_xq.readAll()));
QXmlQuery query;
query.bindVariable("inputDocument",&aqr_r);
query.setQuery(str_query);
bool debug_xml = false;
debug_xml = query.isValid();
QXmlFormatter ser(query, &file);
query.evaluateTo(&ser);
Any ideas about what's causing the problem and how to solve it?
I think the problem is indeed the use of the text stream to consume the opened file, if I don't use that and simply use the code
QFile aqr_xq(queryFile);
aqr_xq.open(QIODevice::ReadOnly);
QFile file(outputFile);
file.open(QIODevice::ReadWrite);
QFile aqr_r;
aqr_r.setFileName(inputFile);
aqr_r.open(QIODevice::ReadOnly);
const QString str_query(QString::fromLatin1(aqr_xq.readAll()));
QXmlQuery query;
query.bindVariable("inputDocument",&aqr_r);
query.setQuery(str_query);
bool debug_xml = false;
debug_xml = query.isValid();
QXmlFormatter ser(query, &file);
query.evaluateTo(&ser);
then indeed the error is in the XQuery and is raised as
Error XPTY0004: Required cardinality is zero or one("?"); got cardinality one or more("+").
You haven't said which output you want to create but if you I change the XQuery to e.g.
declare variable $inputDocument external;
doc($inputDocument)/cookbook/recipe/title/<p>{string()}</p>
then the C++ code runs fine.
Note also that you can load the XQuery directly from a file by using
query.setQuery(QUrl(queryFile));

Add dynamic variables to an url

I would like to add dynamic variables to an url example:
QNetworkRequest req( QUrl( QString("http://website.com/?test=1&id=1") ) );
But when i try this:
// the HTTP request
varUrl = "http://website.com/?test=";
varUrl += info;
varUrl += "&id=";
varUrl += info_2;
QNetworkRequest req( QUrl( QString(varUrl) ) );
QNetworkReply *reply = mgr.get(req);
eventLoop.exec(); // blocks stack until "finished()" has been called
i get this error:
The error message you posted is partly unrelated. Your actual problem is this:
QNetworkRequest req( QUrl( QString(varUrl) ) );
This is treated as a function declaration. This is a corner case in C++ and it's commonly referred to as the "most vexing parse". See https://en.wikipedia.org/wiki/Most_vexing_parse for an explanation.
In any event, use the QUrl::fromUserInput() static function instead of passing the query string directly. This will encode the query correctly (otherwise you'd need to manually encode the query correctly by hand.) So in short, change the above line to:
QNetworkRequest req(QUrl::fromUserInput(varUrl));
This also fixes the parsing issue; the above is treated correctly like a variable definition, not a function declaration, and your code should now compile fine.
As a side-note, you can use the QString::arg() function to construct your string in one go, without having to use append (+=) operations. So you can construct your URL string like this:
varUrl = QString("http://website.com/?test=%1&id=%2").arg(info).arg(info_2);
%1 will be replaced with the contents of info, and %2 with the contents of info_2.
According to the documentation:
The QUrlQuery class provides a way to manipulate a key-value pairs in
a URL's query.
It is used to parse the query strings found in URLs like the
following:
Posible solution is to use QUrlQuery:
QString info = "1";
QString info_2 = "1";
QUrl url("http://website.com/");
QUrlQuery query;
query.addQueryItem("test", info);
query.addQueryItem("id", info_2);
url.setQuery(query);

QFileDialog in c++: "no matching function for call"

I want to let the user choose a folder so I can display and sort its contents somewhere else. The best way to do this seems to be using QFileDialog. Here's a snippet of the code I'm using:
> #include <QFileDialog>
.....
void someEvent(){
QString path = QFileDialog::getExistingDirectoryUrl(this, tr("Choose a Folder"), QDir::home());
}
When I try to compile this I get the error:
no matching function for call to QFileDialog::getExistingDirectoryUrl(MainWindow*, QString, QDir) path = QFileDialog::getExistingDirectoryUrl(this, tr("Choose a Folder"), QDir::home());
Note: I'm running Fedora 25 on this PC and I'm wondering whether that might be the issue?
You have 2 choices depending on your needs, the first one being the best :
getExistingDirectory :
QString path = QFileDialog::getExistingDirectory(this,tr("Choose a Folder"),QDir::homePath());
getExistingDirectoryUrl :
QUrl url = QFileDialog::getExistingDirectoryUrl(this,tr("Choose a Folder"),QUrl(QDir::homePath()));
QString path = url.toString();

Passing values through links in QT

I'm writing a program in C++ and qt4 that is supposed to generate a various number (hundreds )of clickable links in a QTextBrowser depending on data from input files.
The idea is that when the user clicks one of these links a value will be passed to a function named 'on_QTextBrowser_anchorClicked(QUrl)'.
I have created a QTextBrowser which displays HTML code and I manage to create different links to every element added. The problem lies within passing the Url defined in href="URL" to the QUrl.
When setOpenLinks for the QTextBrowser is "true", and I print the URL I get the correct result. But I can't pass this URL (which is a value and not a real URL) to a function.
When setOpenLinks is "false", the anchorClicked(Url) function passes "" as the Url and here I would like to have the URL printed when setOpenLinks=true.
How can I achieve this? Is there a better way (probably is) to connect a various number (approx. between 50-1000) of generated links to a function using QTextBrowser.
My code:
Compassindex.cpp
void CompassIndex::on_seqBrowser_anchorClicked(QUrl input)
{
QString Input = input.toString();
QByteArray nByte = Input.toUtf8();
std::cerr<<Input.data(); //Print Url on the screen to ensure value is passed
}
void CompassIndex::readfile()
{
QString Line;
Int number_out=0;
... //Imports data that will be printed in the QTextBrowser
... //loop for creating links for n number of elements
Line="<a href=\"";
Line+=number_out; //the value (fake Url) that I want to pass to anchorClicked()
Line+="\">";
Line+=nameArr[n]; //inserts the name for the link
Line+="</a>";
number_out++;
...
ui->seqBrowser->insertHtml(Line);
... //end of loop
}
Many thanks for your reply!
I'm using QTextBrowser to provide an actionable user interface for pqConsole. You can read more about in this answer.
I pass around Prolog invocations, and all seems to be working. My anchorClicked slot is as simple as
void ConsoleEdit::anchorClicked(const QUrl &url) {
query_run(url.toString());
}
Note I also have defined (as dummy)
void ConsoleEdit::setSource(const QUrl &name) {
qDebug() << "setSource" << name;
}
I don't touch setOpenLinks(), that defaults to true according to the docs.

Qt html parsing does not find any tags

I am writing a crawling application. Somewhere in the code Ive got:
//normally the HTML is obtained from web with QNetworkAccessManager & QNetworkReply:
//QString htmlCode = this->reply->readAll();
//exemplary test HTML
QString htmlCode =QString("<html><body>test3</body></html>");
QWebPage page;
QWebFrame * frame = page.mainFrame(); //->setHtml(htmlCode);
frame->setHtml(htmlCode);
QWebElement document = frame->documentElement();
QWebElementCollection links = document.findAll("a");
foreach (QWebElement e, links) {
qDebug() << "exemplary link:" << e.toPlainText();
}
I do realize, that there's been like a milion of topics about parsing html in qt here, but i have no idea, what is wrong here...
Mmm... I'm not sure the setHtml()works fully synchronously, i.e. I think the frame content is not fully parsed at that time and thus the DOM content is not yet available.
You should try to connect to void QWebFrame::loadFinished ( bool ok ) and do your DOM crawling there.