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

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

Жанры

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);

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

Свадьба по приказу, или Моя непокорная княжна

Чернованова Валерия Михайловна
Любовные романы:
любовно-фантастические романы
5.57
рейтинг книги
Свадьба по приказу, или Моя непокорная княжна

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Отец моего жениха

Салах Алайна
Любовные романы:
современные любовные романы
7.79
рейтинг книги
Отец моего жениха

Вадбольский

Никитин Юрий Александрович
1. Вадбольский
Фантастика:
попаданцы
5.00
рейтинг книги
Вадбольский

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

В зоне особого внимания

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

Таня Гроттер и магический контрабас

Емец Дмитрий Александрович
1. Таня Гроттер
Фантастика:
фэнтези
8.52
рейтинг книги
Таня Гроттер и магический контрабас

Бастард Императора. Том 2

Орлов Андрей Юрьевич
2. Бастард Императора
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бастард Императора. Том 2

Кодекс Крови. Книга ХI

Борзых М.
11. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХI

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Потусторонний. Книга 1

Погуляй Юрий Александрович
1. Господин Артемьев
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Потусторонний. Книга 1