问题
All my source file are UTF-8 converted.
All my files Im opening are UTF-8.
My application is opening UTF-8 coded file which contains translated text for 3 languages: English, Polish and Russian and is saving the data to a file into 3 separate encoded blocks: Windows-1250 (English), Windows-1250 (Polish) and Windows-1251 (Russian) - yes that's right Im mixing encoding type inside one file which is then used by third-party device which know how to handle that.
Iv got a test program which worked flawlessly under Qt4 and now it stopped working (text is saved as ????????) when I moved to Qt5:
test_encoding.cpp
test_encoding::test_encoding(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); QString d; QFile f(QDir::currentPath() + "/input.txt"); if( f.open( QIODevice::ReadOnly | QIODevice::Text ) ) { d = f.readAll(); f.close(); } QFile ff(QDir::currentPath() + "/output.txt"); if( ff.open( QIODevice::WriteOnly | QIODevice::Text ) ) { QTextStream t(&ff); auto cutf8 = QTextCodec::codecForName("UTF-8"); auto cw50 = QTextCodec::codecForName("windows-1250"); auto cw51 = QTextCodec::codecForName("windows-1251"); // ____Block 1 t.setCodec(cutf8); t << d << "\r\n"; t << cutf8->fromUnicode(d) << "\r\n"; t.flush(); // ____Block 2 t.setCodec(cw50); t << d << "\r\n"; t << cw50->fromUnicode(d) << "\r\n"; t.flush(); // ____Block 3 t.setCodec(cw51); t << d << "\r\n"; t << cw51->fromUnicode(d) << "\r\n"; t.flush(); } ff.close(); QCoreApplication::quit(); }
input.txt (UTF-8 without BOM)
Użytkownik niezalogowany
Not logged-in user
Не зарегистрированный
- output.txt (multi code page blocks)
____Block 1:
Użytkownik niezalogowany
Not logged-in user
Не зарегистрированный
Użytkownik niezalogowany
Not logged-in user
Не зарегистрированный
____Block 2:
U࠹tkownik niezalogowany
Not logged-in user
?? ??????????????????
U?ytkownik niezalogowany
Not logged-in user
?? ??????????????????
____Block 3:
U࠹tkownik niezalogowany
Not logged-in user
?? ??????????????????
U?ytkownik niezalogowany
Not logged-in user
?? ??????????????????
It appears it is possible to save the text only to UTF-8 which is not suitable for me - i need to use code pages Windows-1251 and Windows-1250.
Is it possible in Qt5 to convert from UTF-8 to other code pages?
回答1:
There is a bug in Qt 5 which Iv reported to Qt: https://bugreports.qt.io/browse/QTBUG-42498
At the moment a workaround is to create a new QTextStream object every time you want to change the code page - after QTextStream::flush() has been executed it is NOT possible to change the code page with QTextStream::setCodec() - check description of the bug in the link above. The problem is in line 5 in the source of QIcuCodec::getConverter() - http://pastebin.com/2dEcCyET
So the code which does not work in Qt 5 (and did work in Qt 4.8.4) written this way:
QFile f;
QTextStream ts(&f);
ts.setCodec("Windows-1250");
ts << englishTranslationBlock();
ts << polishTranslationBlock();
ts.flush();
ts.setCodec("Windows-1251");
ts << russianTranslationBlock();
ts.flush();
f.close();
To work around the reported bug, the code must create a new QTextStream to allow the Codec to change. The code will work when written this way:
QFile f;
QTextStream* ts = new QTextStream(&f);
ts->setCodec("Windows-1250");
ts << englishTranslationBlock();
ts << polishTranslationBlock();
ts->flush();
delete ts;
ts = new QTextStream(&f);
ts->setCodec("Windows-1251");
ts << russianTranslationBlock();
ts->flush();
f.close();
来源:https://stackoverflow.com/questions/26803384/qt-5-encoding-problems-utf-8-windows-1250-windows-1251