Чтение онлайн

на главную - закладки

Жанры

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

Запрос является двоичным блоком следующего формата:

• quint16 — размер блока в байтах (не учитывая данное поле),

• quint8 — тип запроса (всегда «S»),

• QString — пункт отправления,

• QString — пункт прибытия,

• QDate — дата поездки,

• QTime — примерное время отправления или прибытия,

• quint8 — признак времени отправления («D») или прибытия («А»).

Сначала мы записываем данные в массив типа QByteArray с

именем block. Мы не можем писать данные непосредственно в QTcpSocket, поскольку мы не знаем размер блока, который будет отсылаться первым, пока не разместим все данные в блоке.

Сначала мы записываем 0 в поле размера блока и затем размещаем остальные данные. Затем мы делаем вызов seek(0) для устройства ввода—вывода (для установки на начало буфера QBuffer, создаваемого автоматически классом QDataStream), чтобы встать на начало массива байтов и переписать первоначальный 0 фактическим размером блока данных. Эта величина рассчитывается как размер блока за вычетом sizeof(quint16) (то есть 2), чтобы исключить поле с размером блока из общей суммы байтов. После этого мы вызываем функцию write для объекта QTcpSocket, чтобы отослать этот блок на сервер.

01 void TripPlanner::updateTableWidget

02 {

03 QDataStream in(&tcpSocket);

04 in.setVersion(QDataStream::Qt_4_1);

05 forever {

06 int row = tableWidget->rowCount;

07 if (nextBlockSize == 0) {

08 if (tcpSocket.bytesAvailable < sizeof(quint16))

09 break;

10 in >> nextBlockSize;

11 }

12 if (nextBlockSize == 0xFFFF) {

13 closeConnection;

14 statusLabel->setText(tr("Found %1 trip(s)").arg(row));

15 break;

16 }

17 if (tcpSocket.bytesAvailable < nextBlockSize)

18 break;

19 QDate date;

20 QTime departureTime;

21 QTime arrivalTime;

22 quint16 duration;

23 quint8 changes;

24 QString trainType;

25 in >> date >> departureTime >> duration >> changes >> trainType;

26 arrivalTime = departureTime.addSecs(duration * 60);

27 tableWidget->setRowCount(row + 1);

28 QStringList fields;

29 fields << date.toString(Qt::LocalDate)

30 << departureTime.toString(tr("hh:mm"))

31 << arrivalTime.toString(tr("hh:mm"))

32 << tr("%1 hr %2 min").arg(duration / 60).arg(duration % 60)

33 << QString::number(changes) << trainType;

34 for (int i = 0; i < fields.count; ++i)

35 tableWidget->setItem(row, i, new QTableWidgetItem(fields[i]));

36 nextBlockSize = 0;

37 }

38 }

Слот updateTableWidget

подсоединяется к сигналу readyRead класса QTcpSocket, который генерируется всякий раз при получении QTcpSocket новых данных от сервера.

Сервер пересылает нам список возможных железнодорожных рейсов, которые удовлетворяют критерию пользователя. Каждый рейс передается в виде одного блока, и каждый блок начинается с поля размера блока. Цикл forever необходим, потому что мы не обязательно получаем от сервера блоки по одному [7] . Мы можем получить целый блок или только его часть или полтора блока либо даже все блоки сразу.

Рис. 14.2. Блоки приложения Trip Server.

7

Ключевое слою forever обеспечивается Qt. Оно просто разворачивается в оператор for (;;).

Итак, как действует цикл forever? Если переменная nextBlockSize равна 0, это означает, что мы не прочитали размер следующего блока. Мы пытаемся прочитать его (предполагается, что имеется по крайней мере 2 байта). Сервер использует значение 0xFFFF в поле размера блока для указания на то, что все данные переданы, и поэтому, если мы обнаруживаем это значение, мы знаем, что достигнут конец.

Если размер блока не равен 0xFFFF, мы пытаемся считать следующий блок. Во-первых, мы проверяем наличие блока байтов необходимого размера. Если его нет, мы прерываем цикл. Сигнал readyRead будет вновь сгенерирован, когда станет доступно больше данных, и мы попытаемся повторить процедуру.

Если мы уверены, что получен целый блок, мы можем спокойно использовать оператор >> для QDataStream для извлечения относящейся к поездкам информации, и мы создаем элементы QTableWidgetItem с этой информацией. Полученный от сервера блок имеет следующий формат:

• quint16 — размер блока в байтах (не учитывая данное поле),

• QDate — дата отправления,

• QTime — время отправления,

• quint16 — длительность поездки (в минутах),

• quint8 — количество пересадок,

• QString — тип поезда.

В конце мы вновь устанавливаем переменную nextBlockSize на 0 для указания того, что размер следующего блока неизвестен и его необходимо считать.

01 void TripPlanner::closeConnection

02 {

03 tcpSocket.close;

04 searchButton->setEnabled(true);

Поделиться:
Популярные книги

Я царь. Книга XXVIII

Дрейк Сириус
28. Дорогой барон!
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Я царь. Книга XXVIII

Полигон

Гостева Ирина
S.T.A.L.K.E.R.
Фантастика:
боевая фантастика
7.78
рейтинг книги
Полигон

Газлайтер. Том 27

Володин Григорий Григорьевич
27. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 27

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Целеполагание

Владимиров Денис
4. Глэрд
Фантастика:
фэнтези
боевая фантастика
рпг
5.00
рейтинг книги
Целеполагание

Неведомые дороги (сборник)

Кунц Дин Рей
Фантастика:
ужасы и мистика
8.00
рейтинг книги
Неведомые дороги (сборник)

Кодекс Охотника. Книга XXXVIII

Винокуров Юрий
38. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
юмористическое фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVIII

Кодекс Охотника. Книга VII

Винокуров Юрий
7. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
4.75
рейтинг книги
Кодекс Охотника. Книга VII

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Протокол "Наследник"

Лисина Александра
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Протокол Наследник

Мастер решений

Земляной Андрей Борисович
3. Специалист по выживанию
Фантастика:
боевая фантастика
космическая фантастика
6.20
рейтинг книги
Мастер решений

Натиск

Осадчук Алексей Витальевич
12. Последняя жизнь
Фантастика:
аниме
фэнтези
попаданцы
6.20
рейтинг книги
Натиск

Князь Андер Арес 3

Грехов Тимофей
3. Андер Арес
Фантастика:
рпг
аниме
фэнтези
5.00
рейтинг книги
Князь Андер Арес 3

Ученик. Книга 4

Первухин Андрей Евгеньевич
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Ученик. Книга 4