I have a problem with Qt5, QStrings and german Umlaute like ä, ö and ü-char. I read data of a 1024 byte header, display it in a form in my app and edit some entries. Everytime I write a german Umlaut in a QLineEdit and process it, I get 2 Bytes instead of 1 Byte - because QString does need 2 Bytes for each character since Qt5.
I've tried this:
QString str = rs_Position1_QLE->text();
QByteArray ba = str.toLatin1();
qDebug() << "ba:" << ba;
Console: ba: "S\xF6ndenlabor" the \xF6 stands for the char ö
(saving the file with the header results in EF BF BD for the ö instead of F6)
but even then I get 2 Bytes for every character with an ASCII Code higher than 127.
How can I solve my problem?
Thank you very much for your answers!
Ralf
Sorry for the delay! I've made a little example script and hope that helps:
Stringtest::Stringtest(QWidget *parent)
: QMainWindow(parent) {
this->setWindowTitle("Stringtest");
QWidget *window = new QWidget;
QVBoxLayout *layout = new QVBoxLayout;
QPushButton *OpenFile_QPB = new QPushButton("Open File");
OpenFile_QPB->setFixedSize(100, 50);
Content_QLE = new QLineEdit;
Content_QLE->setMaxLength(20);
Content_QLE->setMinimumWidth(200);
Content_QLE->setMaximumWidth(200);
Content_QLE->setStyleSheet("padding: 5px; font-family: 'Segoe UI', 'Arial', 'Verdana'; font-size: 12px; background-color: white;
border: none; ");
QPushButton *SaveToFile_QPB = new QPushButton("Save to File");
SaveToFile_QPB->setFixedSize(100, 50);
layout->addWidget(OpenFile_QPB);
layout->addWidget(Content_QLE);
layout->addWidget(SaveToFile_QPB);
window->setLayout(layout);
this->setCentralWidget(window);
connect(OpenFile_QPB, SIGNAL(clicked()), this, SLOT(OpenFile()));
}
Stringtest::~Stringtest() { }
void
Stringtest::OpenFile() {
QString fileName = QFileDialog::getOpenFileName(this, "Open file", "C://Semroch.R", "Textfiles (*.txt);; All files (*.*)");
if (fileName.isEmpty())
return;
else {
QFile file(fileName);
file.open(QFile::ReadOnly);
qDebug() << "system name:" << QLocale::system().name();
qDebug() << "codecForLocale:" << QTextCodec::codecForLocale()->name();
while (!file.atEnd()) {
QByteArray qbaLine = file.readLine();
qDebug() << qbaLine;
Content_QLE->setText(qbaLine);
// QString strLine = qbaLine;
// Content_QLE->setText(strLine);
}
}
} // End of void Stringtest::OpenFile()
I have a test.txt, which I load into the script - the content of the textfile is abcdefä.
The display in the QLineEdit is:
abcdef and a question mark in a diamond.
The qDebug() shows me
system name: "de_DE"
codecForLocale: "System"
in the console.
Any ideas? Thank you very much, Ralf
Few possibilities:
Be sure your shell handles utf-8 (if echo -e '\xe2\x82\xac' command doesn't show a €, then you should fix your shell)
Be sure to handle UTF-8 correctly in your application (add those lines in your main() function):
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
First thing to understand is that QByteArray is just a collection of bytes, it says nothing about its content or the encoding used, while QString is a unicode string stored as UTF-16.
So when you do Content_QLE->setText(qbaLine) or QString strLine = qbaLine, you are implicitly converting a QByteArray to a QString. According to QString documentation, it calls QString::fromUtf8().
So if your file is not encoded as UTF-8, but as Latin 1, you will have issues.
If your file is in Latin 1, you should do: Content_QLE->setText(QString::fromLatin1(qbaLine))
The same goes, when you are writing a file:
file.write(str.toUtf8()); // Write to a UTF-8 file
file.write(str.toLatin1()); // Write to a Latin 1 file
Related
I'm trying to create a simple "To Do list" app in QT Creator while coding the part that loads and saves the list from a file I get stuck on a problem.
If you enter a string like "Do my homework" the program threads the string as it should, but when you load the program again the save file got split in words. So it gets all the entries but each word separated ("Do", "my", "homework").
What is the solution? I tried working with 'char arrays' and 'getline' but they give me nothing but errors.
Here is my code for the save and load parts:
void MainWindow::LoadList(){
std::ifstream load_file("./data.bin");
char loader[255];
while (load_file >> loader){
QString Writer = QString::fromStdString(loader);
ui->lstTaskList->addItem(Writer);
}
}
void MainWindow::SaveList(){
std::ofstream save_file("./data.bin");
for (auto i = 0; i < ui->lstTaskList->count(); i++){
QString Saver = ui->lstTaskList->item(i)->text();
std::string saver = Saver.toStdString();
save_file << saver << std::endl;
}
}
Can anyone help me with this, please?
My thanks in advance...
The anwser was using QFile and QByteArray for me, I knew about QFile but it tries using basic "std" c++ till I learned more about QT.
How can I read only first word in every line in a text file while using QFile in Qt?
Thanks.
use
QFile ifile("in.txt");
QString text = txStream.readLine();
QStringList splitline = text.split(" ");
QFile ofile("out.txt");
ofile.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&ofile);
// join QStringList by "\n" to write each single word in an own line
out << splitline.join("\n");
ofile.close();
I am new to Qt and need to prepare a project to send hex commands from rs232.
QString line contains 64bit binary data which i have to convert into hexadecimal and send it through rs232 .
QString a=ui->comboBox->currentText();
QString s1;
s1="./calc "+a;
QProcess p1;
p1.start(s1);
p1.waitForFinished(-1);
QString line ;
//read
QFile file("TeleOutput.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in (&file);
line = in.readAll();
ui->plainTextEdit->setPlainText(line);
So, how to convert 64 bit binary data in QString line to hexadecimal value and transfer it through rs232?
First of all - you should really use QtSerialPort
Second of all - QString is a class, which works with actual string. QByteArray works with raw data. When you write QString line = in.readAll(); it implicitly calls QString(const QByteArray &ba), which uses QString::fromAscii.
Last of all, if you want to process 64bit integers, you should do something like this:
quint64 d;
QDataStream stream(&file);
while (!stream.atEnd())
{
stream >> d;
process(d);
}
Update
Quote:
My problem is that in plainTextEdit
"1111110101000101010101010101010101010101010101010101010......." 64
bit data is populated , i need to convert this data into hex and send it through rs232
Solution:
QString binData = plainTextEdit.toPlainText();
QByteArray result;
while (binData.size() >= 64)
{
quint64 d;
QString dataPiece = binData.left(64);
binData.remove(0, 64);
d = dataPiece.toULongLong(0, 2);
result += QByteArray::number(d);
}
_com->write(result);
_com->flush();
Where _com is a pointer to QtSerialPort, with all parameters set and opened without errors.
Will this work?
QString bozo;
QFile filevar("sometextfile.txt");
QTextStream in(&filevar);
while(!in.atEnd()) {
QString line = in.readLine();
bozo = bozo + line;
}
filevar.close();
Will bozo be the entirety of sometextfile.txt?
Why even read line by line? You could optimize it a little more and reduce unnecessary re-allocations of the string as you add lines to it:
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
QTextStream in(&file);
QString text;
text = in.readAll();
file.close();
As ddriver mentions, you should first open the file using file.open(…); Other than that, yes bozo will contain the entirety of the file using the code you have.
One thing to note in ddriver's code is that text.reserve(file.size()); is unnecessary because on the following line:
text = in.readAll();
This will replace text with a new string so the call to text.reserve(file.size()); would have just done unused work.
I have a text file. I need to read it to a QStringList. there are no line seperators. I mean each line in the text file is in a new line. So is there anyway i can do this?
I assume that every line should be a separate string in the list. Use QTextStream::readLine() in a cycle and on each step append the returned value to the QStringList. Like this:
QStringList stringList;
QFile textFile;
//... (open the file for reading, etc.)
QTextStream textStream(&textFile);
while (true)
{
QString line = textStream.readLine();
if (line.isNull())
break;
else
stringList.append(line);
}
QFile TextFile;
//Open file for reading
QStringList SL;
while(!TextFile.atEnd())
SL.append(TextFile.readLine());
If the file isn't too big, read the whole content into a QString and then split() it into a QStringList.
I like using the QRegExp version to handle linefeed from different platforms:
QStringList sList = s.split(QRegExp("(\\r\\n)|(\\n\\r)|\\r|\\n"), QString::SkipEmptyParts);
I like my code to be fully indented/paranthesized with obvious variable names (they may take longer to type but are much easier to debug) so would do the following (but changing "myTextFile" and "myStringList" to more sensible names, such as "employeeListTextFile")
QFile myTextFile;
QStringList myStringList;
if (!myTextFile.open(QIODevice::ReadOnly))
{
QMessageBox::information(0, "Error opening file", myTextFile.errorString());
}
else
{
while(!myTextFile.atEnd())
{
myStringList.append(myTextFile.readLine());
}
myTextFile.close();
}
The below code reads the file
QFile File("/file_path");
if(!File.open(QIODevice::ReadOnly));
{
qDebug("Error");
}
QTextStream in(&File);
while(!in.atEnd())
{
qDebug()<<ReadAll;
ReadAll=in.readAll();
}
File.close();
Now the file is closed, now split the new line i.e \n here \r is carriage return
List= ReadAll.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);