Название: [РЕШЕНО] В Qt4.8 все нормально, а в Qt5.2 - кракозябры Отправлено: AlexYanky от Апрель 16, 2014, 22:55 В общем проблема такая…. Многими годами раньше кем-то был написан клиент под пропускную систему организации. Этот клиент работает с внешней платой на базе микроконтроллера Микрочип, который контролирует несколько конечных датчиков, работающих с брелоками радиочастотной идентификации и т.д.
Далее эта внешняя плата пишет информацию о прошедшем человеке в базу MySQL. Так вот. Попросили сотрудники написать новый дополнительный клиент. Написал этот новый клиент на С++ с использованием Qt. Получилось. Но все нормально работало в Qt 4.8.4, а в Qt 5.2 все оказалось не очень классно. Возник вопрос в кодировке… В проге с использованием Qt 4.8.4 кириллицу (информацию полученную из базы MySQL) выводит все нормально. Для демонстрации набросал небольшой примерчик. А тотже пример скомпилированный с Qt 5.2 выводит вместо кириллицы в поле с кодеком кракозябры. Что делать? Уже перепробовал много разных вариантов работы с кодировками, ничего не выходит в Qt 5.2. Что же такого разного в Qt 4.8.4 и Qt 5.2, что один и тот же код там работает а в новой Qt нет? Очень прошу помочь! Скрины окна в Qt 4.8.4 и Qt 5.2 забросил в вложения (по другому не получилось..., извините). Вот исходный код демонстрационного примерчика: #include "widget.h" #include <QApplication> #include <QtSql> //для работы с базой данных #include <QVBoxLayout> #include <QLabel> #include <QLineEdit> #include <QMessageBox> #include <QTextCodec> #define CodecWin(str) codecWin->toUnicode(str) #define CodecUtf(str) codecUtf->toUnicode(str) int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; QSqlDatabase m_db; //объект базы данных сервера MySQL QSqlQuery *m_pqueryDB; //для запросов к базе данных сервера MySQL QTextCodec *codecWin; //кодеки для работы в программе QTextCodec *codecUtf; QTextCodec *codecUtf2; QString m_Query; //строка запроса к базе данных QString m_LastName; QByteArray m_LastName2; //инициализируем используемые кодировки для шрифтов codecWin = QTextCodec::codecForName("Windows-1251"); codecUtf = QTextCodec::codecForName("UTF-8"); //codecWin = QTextCodec::codecForLocale(); //инициализируем драйвер MySQL m_db = QSqlDatabase::addDatabase("QMYSQL"); m_pqueryDB = new QSqlQuery; m_db.setHostName("192.168.0.101"); //а можно вмето IP-адреса указывать имя компа (показано ниже) m_db.setDatabaseName("education"); //название базы данных на сервере MYSQL m_db.setUserName("root"); //имя пользователя на сервере MYSQL m_db.setPassword("YankMotor"); //пароль подключения к серверу MYSQL bool dbcon_ok = m_db.open(); if(!dbcon_ok) //если не удалось подключится к серверу MYSQL { return 0; } //формируем новый запрос к базе данных m_Query = "SELECT id, lastname FROM user WHERE id=14"; if(!(m_pqueryDB->exec(m_Query))) { return 0; } //если все хорошо то переводим результаты запроса из типа QVariant в нужный формат while(m_pqueryDB->next()) { m_LastName = CodecWin(m_pqueryDB->value(1).toByteArray()); //с перекодированием m_LastName2 = m_pqueryDB->value(1).toByteArray(); //и без } codecUtf2 = QTextCodec::codecForUtfText(m_LastName2); //узнаем имя кодека Utf //создаем вертикальное размещение елементов на форме QVBoxLayout* mainLayout = new QVBoxLayout(&w); //создаем элементы управления формы QLabel *label1 = new QLabel(CodecUtf("С кодеком")); QLabel *label2 = new QLabel(CodecUtf("Без кодека")); QLabel *label3 = new QLabel(CodecUtf("Имя кодека codecForUtfText")); QLineEdit *lineedit1 = new QLineEdit(m_LastName); QLineEdit *lineedit2 = new QLineEdit(m_LastName2); QLineEdit *lineedit3 = new QLineEdit(codecUtf2->name()); //и выводим имя кодека Utf //добавляем элементы в вертикальное размещение на форме mainLayout->addWidget(label1); mainLayout->addWidget(lineedit1); mainLayout->addWidget(label2); mainLayout->addWidget(lineedit2); mainLayout->addWidget(label3); mainLayout->addWidget(lineedit3); w.show(); return a.exec(); } Название: Re: В Qt4.8 все нормально, а в Qt5.2 - кракозябры Отправлено: gil9red от Апрель 16, 2014, 23:34 В Qt5, как я помню, utf по умолчанию стоит, поэтому можно и не конвертировать в него :)
Название: Re: В Qt4.8 все нормально, а в Qt5.2 - кракозябры Отправлено: carrygun от Апрель 17, 2014, 04:36 Была у меня похожая проблема, можно почитать в этой теме (http://www.prog.org.ru/index.php?topic=26562).
Название: Re: В Qt4.8 все нормально, а в Qt5.2 - кракозябры Отправлено: AlexYanky от Апрель 17, 2014, 14:55 В Qt5, как я помню, utf по умолчанию стоит, поэтому можно и не конвертировать в него :) Да, но если я просто ничего не перекодирую (не важно это QString или QByteArray) то все равно выводит кракозябры, только другого вида - они представлены в текстовом поле "Без кодеков" на скринформах. Единственное конечно что если я поменяю кодировку по умолчанию на сервере MySql на cp1251, то тогда кирилицу из базы данных выводит нормально и без всякой перекодировки. Но я не могу менять кодировку по умолчанию на сервере MySql (должна стоять latin1) Название: Re: В Qt4.8 все нормально, а в Qt5.2 - кракозябры Отправлено: AlexYanky от Апрель 17, 2014, 15:27 Была у меня похожая проблема, можно почитать в этой теме (http://www.prog.org.ru/index.php?topic=26562). Спасибо за ответ. Прочитал тему, но не знаю что шерстить в драйвере Qt на MySql, для меня пока тяжело... Название: Re: В Qt4.8 все нормально, а в Qt5.2 - кракозябры Отправлено: AlexYanky от Апрель 18, 2014, 17:37 Ура!!! Покопавшись и просмотрев хексовые значения полученных строк в Qt 4.8 и Qt 5.2 убедился что в Qt 5.2 требуется перекодировка из юникода обратно в latin-1, а затем уже необходимо перекодировать latin-1 в windows-1251.
Вот что помогло: #define CodecWinToUni(str) CodecWinToUni->toUnicode(str) #define CodecUtfToUni(str) CodecUtfToUni->toUnicode(str) #define CodecLatinFromUni(str) codecLatin->fromUnicode(str) //добавил вот это QTextCodec *CodecWinToUni; //кодеки для работы в программе QTextCodec *CodecUtfToUni; QTextCodec *codecLatin; //добавил вот это //инициализируем используемые кодировки для шрифтов CodecWinToUni = QTextCodec::codecForName("Windows-1251"); CodecUtfToUni = QTextCodec::codecForName("UTF-8"); codecLatin = QTextCodec::codecForName("ISO 8859-1"); //добавил вот это //и далее в цикле написал следующее, что и помогло while(m_pqueryDB->next()) { m_LastName = m_pqueryDB->value(1).toString(); //без кодека m_LastName2 = m_pqueryDB->value(1).toByteArray(); //и без кодека m_LastName = CodecWinToUni(CodecLatinFromUni(m_LastName)); //и вот это добавил с кодеком, ура помогло!!! } теперь и обеих версиях Qt прекрасно выводит кириллицу из моей базы данных. Надеюсь это решение кому-нибудь поможет!!! Всем спасибо! |