Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Firefox от Сентябрь 23, 2013, 07:53



Название: 2 небольших вопроса
Отправлено: Firefox от Сентябрь 23, 2013, 07:53
Здравствуйте. Буду очень благодарна если вы мне поможете в следующих вопросах:
1) я пересылаю по сети строку из смеси латиницы с кириллицей. при отправке на клиенте все нормально. но когда на сервере получаю, то вместо русских букв выводит всякую кракозябру. И в клиенте и на сервере в main.cpp добавлены следующие строки
Код:
 QTextCodec *utfcodec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForTr(utfcodec);
    QTextCodec::setCodecForCStrings(utfcodec);
    QTextCodec::setCodecForLocale(utfcodec);

Вопрос в том как мне правильно из QByteArray после функции read() получить правильный русский текст.

2)Имеется QProgressBar, работаю в Windows 7, как мне применить к нему стиль Plastique(для того чтоб была сплошная полоса посередине а не прерывистые черточки).в примере имеющимся в qt немного не разобралась, мне к одному элементу только надо.


Название: Re: 2 небольших вопроса
Отправлено: Bepec от Сентябрь 23, 2013, 08:40
1) Надо декодировать ответ. Там же вам байты просто пришли, ваши все установки работают на строки.
Пример как надо сделать возьмите из assistent'a из главы QTextCodec.

2) setStyle примените для прогрессБара. QPlastiqueStyle.


Название: Re: 2 небольших вопроса
Отправлено: LisandreL от Сентябрь 23, 2013, 08:57
1) Покажите как преобразуете QString в QByteArray (или const char*) и обратно.


Название: Re: 2 небольших вопроса
Отправлено: Firefox от Сентябрь 23, 2013, 09:03
я приравниваю строке конечно чтоб потом вывести на экран результат
Код:
 QByteArray arrData;
arrData= socket_in->read(NextBlockSize);
        qDebug()<<"in arrData="<<arrData;

        if(arrData.size()>1)
        {
            QString pak=(QString)(arrData);
но в строке все равно бяка.


Название: Re: 2 небольших вопроса
Отправлено: Firefox от Сентябрь 23, 2013, 09:07
компилятор ругается на такое применение
Код:
 ui->Pb_PRD->setStyle(QPlastiqueStyle);
ui->Pb_PRD - это QProgressBar


Название: Re: 2 небольших вопроса
Отправлено: Bepec от Сентябрь 23, 2013, 09:14
1) Открываем ассистент,  вбиваем туда QPlastiqueStyle и видим, что это класс. Потому подписываем инклуды в проект и создаём объект класса. И уже в setStyle суём класс.

2)
Код:
QString pak(arrData);
попробуйте.


Название: Re: 2 небольших вопроса
Отправлено: Firefox от Сентябрь 23, 2013, 09:44
спасибо за помощь.


Название: Re: 2 небольших вопроса
Отправлено: Bepec от Сентябрь 23, 2013, 10:36
А сможете ответить что в вашем коде было неправильно? По поводу второго вопроса?

PS чтобы в дальнейшем не попадать на такие грабли, надо вам понять, что произошло.


Название: Re: 2 небольших вопроса
Отправлено: sergek от Сентябрь 23, 2013, 11:16
На мой взгляд, с точки зрения преобразования кодировки это:
Код:
            QString pak=(QString)(arrData);
и это:
Код:
QString pak(arrData);
эквивалентны. В обоих случаях используется один и тот же конструктор. Разница в том, что в первом случае добавляется операция инициализации присваиванием. Да и запись (T)a считается устаревшей, в стиле C, без проверки компилятором наличия соответствующего конструктора. Лучше ее не использовать.
Надо помнить, что QString содержит строку в Unicode, а в конструкторе QString(const QByteArray& arr) производится преобразование кодировки arr с использованием fromUtf8(). Т.е., если вы уверены, что arrData в utf-8, то все должно быть хорошо.

Поэтому, на мой взгляд, ошибку надо искать не в серверной программе, а в клиентской. А именно в том, как вы исходный текст (а как он представлен?) преобразуете в QByteArray (об этом вам сразу сказала LisandreL). Так что, давайте на обсуждение клиентский код.


Название: Re: 2 небольших вопроса
Отправлено: Bepec от Сентябрь 23, 2013, 11:36
Поправили :)

Неправильно. (Если и я ошибаюсь, поправьте)

Там не используется конструктор. Там используется приведение типов без проверки.

QString pak=(QString)(arrData);
//Эквивалентно
QString pak= reinterpret_cast<QString>(arrData);

А QString pak=QString(arrData);
//Эквивалентно
QString pak(arrData);

Конструктор не вызывается, происходит просто преобразование типов. Соответственно на выходе у нас мусор и кракозябры, ибо arrData это контейнер и приводить его к другому контейнеру недопустимо.  

А в случае с использование конструктора, данные из контейнера извлекаются и преобразовываются корректно.

PS и да, лучше отказаться от C приведения. Хотя в некоторых случаях без него не обойтись, особенно при использовании Win api.



Название: Re: 2 небольших вопроса
Отправлено: kambala от Сентябрь 23, 2013, 12:00
Верес, ты не прав, почитай про конструкторы.

приведение типа необходимо только если отсутствует конструктор с передаваемым типом или передаваемый тип не может быть преобразован ни к одному из принимаемых типов конструктора (но если конструктор explicit, то приведение не будет выполняться).
Цитировать
Надо помнить, что QString содержит строку в Unicode, а в конструкторе QString(const QByteArray& arr) производится преобразование кодировки arr с использованием fromUtf8(). Т.е., если вы уверены, что arrData в utf-8, то все должно быть хорошо.
вообще-то с fromAscii() (во всяком случае в Qt 4).


Название: Re: 2 небольших вопроса
Отправлено: Bepec от Сентябрь 23, 2013, 12:32
Ссылочку про конструкторы не дадите? :)


Название: Re: 2 небольших вопроса
Отправлено: sergek от Сентябрь 23, 2013, 15:50
вообще-то с fromAscii() (во всяком случае в Qt 4).
Прошу прощения, не обратил внимания на "setCodecForCStrings", указал преобразование для Qt 5 :(

Ссылочку про конструкторы не дадите? :)
Страуструп, специальное издание, 2011: подразделы 10.4.4.1 (копирование объектов), 6.2.7, 6.2.8 (явное приведение типов).


Название: Re: 2 небольших вопроса
Отправлено: sergek от Сентябрь 23, 2013, 16:10
вообще-то с fromAscii() (во всяком случае в Qt 4).
После некоторого раздумья  ???, в этом и может быть причина - на сервер данные попадают в utf-8, а преобразуются в QString с помощью fromAscii().
Получается, на сервере нужно так:
Код:
QTextCodec *utfcodec = QTextCodec::codecForName("UTF-8");
QString pak=utfcodec->toUnicode(arrData);


Название: Re: 2 небольших вопроса
Отправлено: Igors от Сентябрь 23, 2013, 16:29
приведение типа необходимо только если отсутствует конструктор с передаваемым типом или передаваемый тип не может быть преобразован ни к одному из принимаемых типов конструктора (но если конструктор explicit, то приведение не будет выполняться).
Плюс еще один случай - для принимающего должен быть разрешен конструктор копирования, (по умолчанию или свой), хотя он и не используется. Пример
Код
C++ (Qt)
struct CTest {
CTest( int a = 0 );
 
private:
CTest( const CTest & ) {}
};
 
CTest test = 1;   // ошибка


Название: Re: 2 небольших вопроса
Отправлено: kambala от Сентябрь 24, 2013, 12:58
Ссылочку про конструкторы не дадите? :)
помимо стандарта — любая книжка по С++
приведение типа необходимо только если отсутствует конструктор с передаваемым типом или передаваемый тип не может быть преобразован ни к одному из принимаемых типов конструктора (но если конструктор explicit, то приведение не будет выполняться).
Плюс еще один случай - для принимающего должен быть разрешен конструктор копирования, (по умолчанию или свой), хотя он и не используется. Пример
Код
C++ (Qt)
struct CTest {
CTest( int a = 0 );
 
private:
CTest( const CTest & ) {}
};
 
CTest test = 1;   // ошибка
в данном примере ошибка возникает лишь потому, что отсутствует реализация паблик конструктора — после добавления тела компилируется без ошибок (компилятор от студии 2012)


Название: Re: 2 небольших вопроса
Отправлено: Igors от Сентябрь 24, 2013, 13:50
в данном примере ошибка возникает лишь потому, что отсутствует реализация паблик конструктора — после добавления тела компилируется без ошибок (компилятор от студии 2012)
Я бы на такой авторитет как MSVC не ссылался :)  gcc вообще error, icc отсыпает варнинг
Цитировать
warning #734: "CTest::CTest(const CTest &)" (declared at line 12), required for copy that was eliminated, is inaccessible



Название: Re: 2 небольших вопроса
Отправлено: kambala от Сентябрь 24, 2013, 21:14
что было под рукой — тем и проверил :) действительно, clang тоже выдает ошибку «вызов приватного конструктора».