QString from Punycode QUrl - c++

If I put url http://www.äsdf.de/bla/bla into QUrl, how can I then restore url with original symbols?
It's ok that QUrl will fix some characters, but I'd like to display original äsdf in url instead of xn--sdf-pla.
I am aware about QString QUrl::fromAce(const QByteArray &domain), but it requires QByteArray instead of QUrl instance.

You can use QUrl::toDisplayString with the default PrettyDecoded formatting option, or any other value among enum ComponentFormattingOption:
QUrl url{"http://www.äsdf.de/bla/bla"};
QString original_string =
url.toDisplayString(); // default is QUrl::PrettyDecoded
QString original_string_with_encoded_spaces =
url.toDisplayString(QUrl::EncodeSpaces);

Related

How Do I Save and Load Data Using QSettings?

I'm a complete beginner to QT5, I searched YouTube for any QSettings tutorials and only found 2 of them, both in Spanish.
I'm trying to store simple text from a textEdit and then load it on save/load button click. So far I have not been able to accomplish this. Here's my code so far, no errors, it just doesn't work.
Widget.cpp
void Widget::saveText(QString key, QString text)
{
QSettings settings("App", "BillReminder");
settings.beginGroup("Text");
settings.setValue(key + "t", text);
settings.endGroup();
}
QString Widget::loadText(QString key)
{
QSettings settings("App", "BillReminder");
settings.beginGroup("Text");
settings.value(key + "t", text).toString();
settings.endGroup();
return QString(text);
}
void Widget::on_saveButton_clicked()
{
saveText("textEdit", text);
}
void Widget::on_loadButton_clicked()
{
QString text1 = loadText(text);
ui->textEdit->setText(text1);
}
widget.h - class Widget : public QWidget
private:
Ui::Widget *ui;
QString text;
void saveText(QString key, QString text);
QString loadText(QString key);
void SetText(QString key);
The problem is in your loadText() method. QSettings::value() is a function that returns a value retrieved from the QSettings storage. The second parameter is only a default value, that would be returned in case your settings storage doesn't contain the requested key.
QString Widget::loadText(QString key)
{
QSettings settings("App", "BillReminder");
settings.beginGroup("Text");
QString theValue = settings.value(key + "t", text).toString();
settings.endGroup();
return theValue;
}
This code example contains many issues.
don't shadow variable names (e.g. "text" is method argument and member variable); use e.g. underscore to indicate member variables
above answer about reading values as return value solve one issue as well
on_saveButton is using as a settings key a "textEdit" string but on_loadButton is used wrong "text" member variable string as key -> you want use the same string to load stored variable i.e. you are reading something else just now.
you are saving member variable "text" that is not initialised in your example i.e. it may be empty; and later you are setting UI text edit with stored settings (empty string in your example?)
Please go through QSettings Qt documentation for working example.

External vs internal declaration of QByteArray

I have currently some problems with the QSerialPort: When I am using the function from an example which looks like
QKeyEvent *e;
emit getData(e->text().toLocal8Bit());
connect(console, SIGNAL(getData(QByteArray)), this, SLOT(writeData(QByteArray)));
void MainWindow::writeData(const QByteArray &data)
{
qDebug() << "Data is to write: " << data;
serial->write(data);
}
then the receiving device can work with the data. But when I change the function writeData() to
void MainWindow::writeData(const QByteArray &data)
{
QString a = "Q";
QByteArray b = a.toLocal8Bit();
serial->write(b);
}
the receiving device can not work with the received data. Where is the difference between those two approaches?
Update: I found out that apparently the data is only usefully transferred if I press Enter after typing the letters. Somehow the '\n' gets lost in the conversion from QString to QByteArray. How can I keep it?
you should add an enter to your Qstring like this
QString a = "Q\x00D";
In the example you have given, there is no "\n" in the QString! It is not getting lost, it is not there in the first place.
If a newline is necessary, then construct the String as QString a = "Q\n".
You can also construct the QByteArray directly from a character array rather than going through a char array -> QString -> QByteArrray conversion sequence, like so:
QByteArray b("Q\n");
EDIT: I realized that your contrived example where you are just sending the letter "Q" is probably a debug attempt, not your real code. In reality, you're getting data in as a QByteArray from some other signal that is emitting a QByteArray. That QByteArray that you are receiving must not include the newline character in it. If you are reading from a file or user input, then that is normal. Most readline-like functions strip off the trailing newline. If it is always necessary to have a newline, you can simply do something like this in your WriteData method:
void MainWindow::writeData(const QByteArray &data)
{
serial->write(data);
serial->write("\n");
}
If sometimes the passed-in QByteArray has a newline at the end and sometimes not, and your receiving device cannot handle redundant newlines, then you'd need to check whether data ends with a newline and only write the "\n" if it does not.
what if you make the QByteArray like this
QByteArray b(&a);

Conflict type QString and std::string in a parameter

I think my problem is simple to solve, but due to my lack of knowledge, I can't find the answer.
I have this structure :
struct variableOutil {
std::string Nom;
float Valeur;
std::string Module;
std::string Unite;
std::string Format;
std::string Accesibilite;
std::string Description ;
};
And the problem come from here :
struct variableOutil ToleranceTensionAvion;
ToleranceTensionAvion.Nom = "ToleranceTensionAvion";
QTableWidgetItem* newItem = new QTableWidgetItem();
newItem->setText(ToleranceTensionAvion.Nom);
this->ui->variableTableWidget->setItem(1,0,newItem);
I've got this error :
No matching function for call to 'QTableWidgetItem::setText(std::string&)
The problem is that setText need a const QString &text and tell me that I put in parameter a std::string& , I don't understand why does the type don't match, and what's the difference, after all, this is a simple String.
Thank you.
You should convert std::string to QString by :
newItem->setText(QString::fromStdString(ToleranceTensionAvion.Nom));
Or
newItem->setText(QString::fromUtf8(ToleranceTensionAvion.Nom.c_str());
Try:
newItem->setText(QString::fromUtf8(ToleranceTensionAvion.Nom.c_str());
QString allows only Unicode.
std::string just stores the bytes and does not work with encodings. The best way to store your texts would probably be UTF-8 encoding.
They are completely different classes, and std::stringcan not be used in place of QString. You can build QString fromstd::string and pass it.
QString s =QString::fromStdString(ToleranceTensionAvion.Nom);
newItem->setText(s);
just use c._str() on your std::string and it will work for anything that expects a QString

How to parse network hostname + port in qt?

I am currently writing a network application in Qt and need to seperate network adresses in the form:
example.org:1234
into seperate hostname and port QStrings.
Is there a Qt function to easily parse this and check if the given input is correct?
Thanks in advance!
This is quite simple; you just use the QUrl class for this with the constructor, host() and port() methods as follows:
QUrl url("http://example.org:1234")
qDebug() << "Host:" << url.host();
qDebug() << "Port:" << url.port();
As for your comment for avoiding the scheme usage in each url, you could use this:
url.setScheme("ftp");
or
url.setScheme("http");
Yes, you should use the QUrl::fromUserInput function to parse the string, and then the host and port methods of the QUrl object to get the QStrings that you want.
auto url{ QUrl::fromUserInput(address) };
auto host{ url.host() };
auto port{ QString::number(url.port()) };

How to save and load a QJsonDocument to a file?

I am trying to learn how to use JSON and the Qt JSON classes. For example I wnat to create a simple QJsonDocument, save it to a file, load it into a different QJsonDocument and compare results.
I managed to create a QJsonDocument. However there is no simple command in the QJsonDocument interface to save it to a file. The same goes for loading the document from a file.
#include <QJsonObject>
#include <QJsonDocument>
#include <QVariant>
int main()
{
QVariantMap map;
map.insert("integer", 1);
map.insert("double", 2.34);
map.insert("bool", QVariant(true));
map.insert("string", "word");
QJsonObject object = QJsonObject::fromVariantMap(map);
QJsonDocument document;
document.setObject(object);
// ?? save document to file
// ?? load file to document
return 0;
}
This answer shows how to load the document by
reading to a QFile
converting QFile to a QString
converting the QString to a QByteArray
constructing the QJsonDocument from the QByteArray
Is there a more straightforward way to do this?
Personally, I think that code [that you linked to] looks a bit messy. Warning: head compiled code follows.
QJsonDocument loadJson(QString fileName) {
QFile jsonFile(fileName);
jsonFile.open(QFile::ReadOnly);
return QJsonDocument().fromJson(jsonFile.readAll());
}
void saveJson(QJsonDocument document, QString fileName) {
QFile jsonFile(fileName);
jsonFile.open(QFile::WriteOnly);
jsonFile.write(document.toJson());
}
This may not be perfect: it assumes QFile instead of QIODevice, but if you're dealing with only local files maybe it won't matter. You can then use these functions instead of repeating the Json load/save code everytime you need to load/save Json.
No need for converting to string and back. With QSettings and QVariant classes you can easily do that. Create QVariant object from QJsonDocument and save it with QSettings. Look at functions QJsonDocument::fromVariant and QJsonDocument::toVariant. Combine them with QSettings class and specifically void QSettings::setValue ( const QString & key, const QVariant & value ) method, that works well with QVariant and that's it.
Also QSettings class has this constructor QSettings::QSettings ( const QString & fileName, Format format, QObject * parent = 0 )
that would allow you to set path to the file - fileName variable