Russian Qt Forum
Ноябрь 22, 2024, 20:37 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] В Qt4.8 все нормально, а в Qt5.2 - кракозябры  (Прочитано 8062 раз)
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();
}
« Последнее редактирование: Апрель 25, 2014, 15:09 от AlexYanky » Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #1 : Апрель 16, 2014, 23:34 »

В Qt5, как я помню, utf по умолчанию стоит, поэтому можно и не конвертировать в него Улыбающийся
Записан

carrygun
Гость
« Ответ #2 : Апрель 17, 2014, 04:36 »

Была у меня похожая проблема, можно почитать в этой теме.
Записан
AlexYanky
Гость
« Ответ #3 : Апрель 17, 2014, 14:55 »

В Qt5, как я помню, utf по умолчанию стоит, поэтому можно и не конвертировать в него Улыбающийся

Да, но если я просто ничего не перекодирую (не важно это QString или QByteArray) то все равно выводит кракозябры, только другого вида - они представлены в текстовом  поле "Без кодеков" на скринформах. Единственное конечно что если я поменяю кодировку по умолчанию на сервере MySql на cp1251, то тогда кирилицу из базы данных выводит нормально и без всякой перекодировки. Но я не могу менять кодировку по умолчанию на сервере MySql (должна стоять latin1)
Записан
AlexYanky
Гость
« Ответ #4 : Апрель 17, 2014, 15:27 »

Была у меня похожая проблема, можно почитать в этой теме.

Спасибо за ответ. Прочитал тему, но не знаю что шерстить в драйвере Qt на MySql, для меня пока тяжело...
Записан
AlexYanky
Гость
« Ответ #5 : Апрель 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 прекрасно выводит кириллицу из моей базы данных.
Надеюсь это решение кому-нибудь поможет!!!
Всем спасибо!




Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 23.