PDA

View Full Version : unicode character displays ok on Windows, not on Linux



schnitzel
18th February 2011, 02:02
my Qt application uses a text file that contains the degree character '°' (unicode U+00B0). It displays fine when my app runs on windows, but on linux I get: '°'
The text file that contains this character displays fine outside of my app.

I'm puzzled.

ChrisW67
18th February 2011, 08:05
You have a mismatch between the encoding of the text file and what you are telling telling Qt it is. The UTF-8 encoding of U+00B0 is 0xC2 0xB0. Your output is what those two bytes produce when they are interpreted as ISO 8859-1 characters rather than UTF-8.

schnitzel
18th February 2011, 22:33
You have a mismatch between the encoding of the text file and what you are telling telling Qt it is. The UTF-8 encoding of U+00B0 is 0xC2 0xB0. Your output is what those two bytes produce when they are interpreted as ISO 8859-1 characters rather than UTF-8.

but the real kicker is that the same code runs fine when compiled in Qt Creator on windows. I only see the problem on linux - same code, just a rebuild

wysota
18th February 2011, 23:34
That's because Windows and Linux use different "local8Bit" encodings. For Windows this is probably utf-8 while for your Linux it is presumably latin1. Use QString::fromUtf8() to explicitly convert a utf-8 string to Unicode.

schnitzel
19th February 2011, 07:41
That's because Windows and Linux use different "local8Bit" encodings. For Windows this is probably utf-8 while for your Linux it is presumably latin1. Use QString::fromUtf8() to explicitly convert a utf-8 string to Unicode.

The string that contains this character is actually being provided by QSettings as follows:


myset->value("units","").toString();


I tried the following but without success:


QString::fromUtf8(myset->value("units","").toByteArray().constData());

wysota
19th February 2011, 08:17
How do you store the value in the settings?

schnitzel
19th February 2011, 08:39
from a text file which gets stored into QSettings like this:



QSettings("myinifile", QSettings::IniFormat);


I just noticed QSettings::setIniCodec, looks like I need to play with that tomorrow.

schnitzel
20th February 2011, 22:13
Here is what I've tried, still no luck:



QSettings *cfg = new QSettings(fn,QSettings::IniFormat);
cfg->setIniCodec("UTF-8");
...
QString tmp = QString::fromUtf8(myset->value("units","").toByteArray().constData());

wysota
21st February 2011, 01:19
Shouldn't it be:

QString tmp = myset->value("units", "").toString();
?

schnitzel
21st February 2011, 02:02
Shouldn't it be:

QString tmp = myset->value("units", "").toString();
?

that's what I had initially and I just tried it again, still no luck. It is as if the setIniCodec("UTF-8") does nothing.
:confused:

ChrisW67
21st February 2011, 05:59
To make sure I have the situation correct...
You have a UTF-8 encoded INI file that is being read by QSettings. When you retrieve the value of a key and try to interpret it as a QString you get the unexpected result from your first post.

This test program functions correctly if the codec is set before any access to the settings. If I access a setting, even a completely unrelated one, before setting the codec then the file is read and cached as Latin1 text.

#include <QtGui>
#include <QDebug>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QSettings settings("test.ini", QSettings::IniFormat);
// uncomment the following line to break it
// qDebug() << settings.value("missing").toString();
settings.setIniCodec("UTF-8");
qDebug() << settings.value("test").toString();

return app.exec();
}

with


$ cat test.ini
test=°
$ od -tc -tx1 test.ini
0000000 t e s t = 302 260 \n
74 65 73 74 3d c2 b0 0a

outputs


"°"

schnitzel
21st February 2011, 17:54
@ChrisW67: The test program worked fine

And then it dawned on me. :o QSettings is only half of it. I am also reading the ini file contents into a QTextEdit and hence I needed to set the codec there as well even though I'm not displaying the editor right away.
Everything is working now.