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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Кириллица из xml  (Прочитано 18389 раз)
moops
Гость
« : Декабрь 15, 2017, 02:04 »

Здраствуйте. Возникла проблема с отображением русского текста в QTableWidget на клиенте.

На серве лежит xml с кодировкой utf-16.
Данные парсятся в структуры и по запросам клиента отправляются также xml документами.
Подскажите, что делать.

Отправление данных с сервера:
Код:
void ServerWindow::slotDataSend(QString dataToSend)
{
    QByteArray messageForSend;

    QDataStream sendStream(& messageForSend, QIODevice::ReadWrite);
    sendStream.setVersion(QDataStream::Qt_DefaultCompiledVersion);

    sendStream << quint16(0) << dataToSend;
    sendStream.device()->seek(0);
    sendStream << (quint16)(messageForSend.size() - sizeof(quint16));

    tcpConnection->write(messageForSend);
}


Прием на клиенте:
Код:
void MainWindow::readResponse()
{
    static quint16 nextBlockSize = 0;
    QByteArray tmpData;

    QDataStream stream(&MySocket::tcpSocket);
    stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);

    while(true)
    {
        if(nextBlockSize == 0)
        {
            if(MySocket::tcpSocket.bytesAvailable() < sizeof(quint16))
                break;
            stream >> nextBlockSize;
        }
        if(MySocket::tcpSocket.bytesAvailable() < nextBlockSize)
            break;

        while(!stream.atEnd())
        {
            stream >> tmpData;
        }
        nextBlockSize = 0;
    }
    QDomDocument domDoc;
    domDoc.setContent(tmpData);
    QDomElement domElem = domDoc.documentElement();

    parseResponseType(domElem);
}

Для английского все работает без проблем, а с кириллицей беда..

P/s  особо не ругаться, так как начинающий=)
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #1 : Декабрь 15, 2017, 09:21 »

Цитировать
Для английского все работает без проблем, а с кириллицей беда..

А в чем проблема-то? Ошибка, кракозябры?
Записан

ssoft
Программист
*****
Online Online

Сообщений: 584


Просмотр профиля
« Ответ #2 : Декабрь 15, 2017, 10:16 »

Проблема в том, что записывается QString dataToSend, а вычитывается QByteArray tmpData.

Но есть и другие ошибки, например, постоянная перезапись значения

Код
C++ (Qt)
       while(!stream.atEnd())
       {
           stream >> tmpData;
       }
 
Записан
moops
Гость
« Ответ #3 : Декабрь 15, 2017, 10:56 »

Проблема в том, что записывается QString dataToSend, а вычитывается QByteArray tmpData

Так я же dataToSend загоняю в QByteArray messageForSend и отправляю уже его
Или я вас не так понял)

А на счёт перезаписи :  взял пример из интернета, со всеми данными работает вроде.

В любом случае я знаю, что ошибок много, сам их периодически нахожу. Нужен ответ на вопрос:"что делать?"
Записан
moops
Гость
« Ответ #4 : Декабрь 15, 2017, 10:59 »

Цитировать
Для английского все работает без проблем, а с кириллицей беда..

А в чем проблема-то? Ошибка, кракозябры?


Кракозябры, причем в отладчике посмотрел, кракозябры записываются уже  с сервера, а не в таблицу
Записан
ssoft
Программист
*****
Online Online

Сообщений: 584


Просмотр профиля
« Ответ #5 : Декабрь 15, 2017, 11:26 »

Так я же dataToSend загоняю в QByteArray messageForSend и отправляю уже его
Или я вас не так понял)

Загоняете сначала размер quint16, а затем QString

Код
C++ (Qt)
   sendStream << quint16(0) << dataToSend; // QString!
   sendStream.device()->seek(0);
   sendStream << (quint16)(messageForSend.size() - sizeof(quint16));
 

следующая запись только отправляет сериализованные данные через сокет

Код
C++ (Qt)
tcpConnection->write(messageForSend);
 


Принимаете

сначала размер quint16

Код
C++ (Qt)
stream >> nextBlockSize;

затем QByteArray

Код
C++ (Qt)
stream >> tmpData; // QByteArray!

В случае латиницы сериализация QByteArray и QString совпадает.
Записан
moops
Гость
« Ответ #6 : Декабрь 15, 2017, 20:12 »

Так я же dataToSend загоняю в QByteArray messageForSend и отправляю уже его
Или я вас не так понял)

Загоняете сначала размер quint16, а затем QString

Код
C++ (Qt)
   sendStream << quint16(0) << dataToSend; // QString!
   sendStream.device()->seek(0);
   sendStream << (quint16)(messageForSend.size() - sizeof(quint16));
 

следующая запись только отправляет сериализованные данные через сокет

Код
C++ (Qt)
tcpConnection->write(messageForSend);
 


Принимаете

сначала размер quint16

Код
C++ (Qt)
stream >> nextBlockSize;

затем QByteArray

Код
C++ (Qt)
stream >> tmpData; // QByteArray!

В случае латиницы сериализация QByteArray и QString совпадает.

Ладно, я понял. Но я не понимаю, что мне нужно сделать, чтобы все стало хорошо=)
Что делать то?
« Последнее редактирование: Декабрь 16, 2017, 14:24 от moops » Записан
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #7 : Декабрь 17, 2017, 21:41 »

главное, что-бы с мефодицей было все в порядке...
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
ssoft
Программист
*****
Online Online

Сообщений: 584


Просмотр профиля
« Ответ #8 : Декабрь 18, 2017, 08:01 »

Ладно, я понял. Но я не понимаю, что мне нужно сделать, чтобы все стало хорошо=)
Что делать то?

В замешательстве Непонимающий

Ну  для начала типы dataToSend и tmpData сделать идентичными, например, QString.
Записан
moops
Гость
« Ответ #9 : Декабрь 19, 2017, 11:53 »

Ладно, я понял. Но я не понимаю, что мне нужно сделать, чтобы все стало хорошо=)
Что делать то?

В замешательстве Непонимающий

Ну  для начала типы dataToSend и tmpData сделать идентичными, например, QString.

Ну я не совсем дурачок, не помогает)
Записан
ssoft
Программист
*****
Online Online

Сообщений: 584


Просмотр профиля
« Ответ #10 : Декабрь 19, 2017, 12:32 »

Ну вот же работает передача данных. Значит в другом месте ошибка.

Код
C++ (Qt)
QByteArray slotDataSend( const QString & dataToSend )
{
   QByteArray messageForSend;
 
   QDataStream sendStream( &messageForSend, QIODevice::ReadWrite );
   //sendStream.setVersion( QDataStream::Qt_DefaultCompiledVersion );
 
   sendStream << quint16(0) << dataToSend;
   sendStream.device()->seek(0);
   sendStream << quint16( messageForSend.size() - sizeof( quint16 ) );
 
   return messageForSend;
}
 
QString readResponse ( const QByteArray & array )
{
   static quint16 nextBlockSize = 0;
   QString tmpData;
 
   QDataStream stream( array );
   //stream.setVersion( QDataStream::Qt_DefaultCompiledVersion );
 
   while(true)
   {
       if ( nextBlockSize == 0 )
       {
           if ( stream.device()->bytesAvailable() < sizeof(quint16) )
               break;
           stream >> nextBlockSize;
       }
       if ( stream.device()->bytesAvailable() < nextBlockSize )
           break;
 
       stream >> tmpData;
       nextBlockSize = 0;
   }
 
   return tmpData;
}
 
int main(int argc, char *argv[])
{
   QCoreApplication a( argc, argv );
 
   QString text = QString::fromUtf8( "Привет, Русский язык!" );
   QString result = readResponse( slotDataSend( text ) );
 
   qDebug() << QString::fromUtf8( "Исходный текст:" ) << text;
   qDebug() << QString::fromUtf8( "Результат:" ) << result;
 
   return a.exec();
}
 

PS: В консоль только не выводите, там крокозябры могут быть.
Записан
moops
Гость
« Ответ #11 : Декабрь 23, 2017, 13:28 »

Проблема оказалась в считывании самого xml. Он уже оттуда читает кракозябрами.

XML:
Код:
<?xml version="1.0" encoding="UTF-8"?>
<championship>
    <teams>
        <team name="Torpeda" course="45" totalScoring="14" totalMissing="4">
            <players>
                <player num="1" otch="Vital`evich" name="Ivan" fam="Kalashnikov"/>
                <player num="2" otch="Popovich" name="Oleg" fam="Andreev"/>
<player num="3" otch="Ivanovich" name="Kirill" fam="Afanosov"/>
<player num="4" otch="Olegovich" name="Petr" fam="Igorkevich"/>
<player num="5" otch="Petrovich" name="Alex" fam="Voron"/>
<player num="6" otch="Alexseevich" name="Andrey" fam="Dronov"/>
            </players>
        </team>
   </teams>
</championship>


вот само считывание:
Код:
GetChampionshipData chData;
chData.traverseNode();


void GetChampionshipData::traverseNode()
{

    QFile file("C://Users//User//Desktop//work//serrv_v3.2//DATA.xml");
    if(!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(0, "Ошибка",
                             "Не удалось найти DATA.xml", QMessageBox::Ok);
    }
    else
    {
        QDomDocument domDoc;
        domDoc.clear();
        domDoc.setContent(&file);

        QDomElement domElement = domDoc.documentElement();
        traverseTeamNode(domElement);
    }
    file.close();
}



void GetChampionshipData::traverseTeamNode(const QDomNode &node)
{
    QDomElement teamsNode = node.firstChildElement();
    QDomElement teamNode = teamsNode.firstChildElement();

    while(!teamNode.isNull())
    {
        if(teamsNode.tagName() == "teams")
        {

            if(teamNode.tagName() == "team")
            {
                Team tm;
                tm.loadFromNode(teamNode);
                teams.push_back(tm);
            }
            teamNode = teamNode.nextSiblingElement();
        }
    }
}

void Team::loadFromNode(QDomElement &teamNode)
{
    if(!teamNode.attribute("name").isEmpty())
        name = teamNode.attribute("name");                     // здесь читаются кракозябры
    if(!teamNode.attribute("totalScoring").isEmpty())
        scoringGoal = teamNode.attribute("totalScoring").toInt();
    if(!teamNode.attribute("totalMissing").isEmpty())
        missingGoal = teamNode.attribute("totalMissing").toInt();

    QDomElement teamPlayers = teamNode.firstChildElement();
    QDomElement teamPlayer  = teamPlayers.firstChildElement();

    while(!teamPlayers.isNull())
    {
        if(!teamPlayer.isNull())
        {
            if(teamPlayer.tagName() == "player")
            {
                Player player;
                player.loadFromNode(teamPlayer);
                players.push_back(player);
            }
            teamPlayer = teamPlayer.nextSiblingElement();
        }
        else break;
    }
}

void Player::loadFromNode(const QDomElement &playerNode)
{
    if(!playerNode.attribute("num").isEmpty())
        num  = playerNode.attribute("num");
    if(!playerNode.attribute("otch").isEmpty())
        otch = playerNode.attribute("otch");         // здесь читаются кракозябры
    if(!playerNode.attribute("name").isEmpty())
        name = playerNode.attribute("name");    // здесь читаются кракозябры
    if(!playerNode.attribute("fam").isEmpty())
        fam  = playerNode.attribute("fam");        // здесь читаются кракозябры
    if(!playerNode.attribute("goal").isEmpty())
        goal = playerNode.attribute("goal");
}


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


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