QT 4: программирование GUI на С++
Шрифт:
Слот processPendingDatagrams
Функция pendingDatagramSize возвращает размер первой ждущей обработки дейтаграммы. С точки зрения приложения дейтаграммы всегда посылаются и принимаются как один блок данных. Это означает, что при любом количестве байтов дейтаграмма будет считываться целиком. Вызов readDatagram копирует содержимое первой ждущей обработки дейтаграммы в указанный буфер char * (обрезая данные, если размер буфера оказывается недостаточным) и осуществляет переход к следующей необработанной дейтаграмме. После считывания всех дейтаграмм мы разбиваем последнюю из них (имеющую самые свежие значения параметров атмосферного состояния) на составные части и заполняем строки редактирования QLineEdit новыми данными.
Наконец, в функции main мы создаем и показываем объект WeatherStation.
На этом мы завершаем рассмотрение наших примеров по передаче и приему данных с применением протокола UDP. Представленные приложения максимально упрощены, причем приложение Weather Balloon посылает дейтаграммы, а приложение Weather Station получает их. В большинстве реальных приложений в обоих случаях пришлось бы как считывать, так записывать данные на свой сокет. Функциям QUdpSocket::writeDatagram могут передаваться адрес хоста и номер порта, поэтому QUdpSocket может читать с хоста и порта, с которыми он был связан функцией bind, и писать на какой-нибудь другой хост и порт.
Глава 15. XML
XML (Extensible Markup Language — расширяемый язык разметки) — это универсальный формат текстовых файлов, который получил широкое распространение при обмене и хранении данных. Qt обеспечивает два различных программных интерфейса для чтения документов XML; эти интерфейсы входят в состав модуля QtXml:
• SAX (Simple API for XML — простой программный интерфейс для документов XML) позволяет обрабатывать «события синтаксического анализа» непосредственно в приложении в соответствующих виртуальных функциях.
• DOM (Document Object Model — объектная модель документа) преобразует документ XML в структуру в виде дерева, которая затем может обрабатываться в приложении.
Существует много факторов, которые необходимо учитывать в каждом конкретном случае при выборе между DOM и SAX. SAX является интерфейсом более низкого уровня и обычно работает быстрее, что делает его особенно пригодным как для решения простых задач (например, для поиска в документе XML
всех повторений заданного тега), так и для чтения очень больших файлов, которые не помещаются в оперативной памяти. Но для большинства приложений удобство применения DOM перевешивает потенциальные преимущества более высокого быстродействия и более эффективного использования памяти в SAX.Создавать файлы XML можно двумя способами: мы можем сгенерировать XML вручную или представить данные в виде дерева DOM, размещенного в памяти, и «попросить» это дерево записать себя в файл.
Чтение документов XML при помощи интерфейса SAX
SAX является фактическим стандартом программного интерфейса с открытым исходным кодом, который обеспечивает чтение документов XML.
Классы Qt для интерфейса SAX моделируют реализацию SAX2 Java с некоторыми отличиями в названиях для обеспечения принятых в Qt правил обозначений названий классов и их членов. Более подробную информацию относительно SAX можно получить в сети Интернет по адресу http://www.saxproject.org/.
Qt обеспечивает построенный на основе интерфейса SAX парсер документов XML, не предусматривающий проверку их достоверности под названием QXmlSimpleReader. Этот парсер распознает хорошо сформированные документы XML и поддерживает пространства имен XML. Когда парсер обрабатывает документ, он вызывает виртуальные функции в зарегистрированных классах—обработчиках, уведомляющих о возникновении соответствующих событий в ходе синтаксического анализа документа. (Эти события никак не связаны с такими событиями Qt, как события клавиатуры и события мышки.) Например, пусть парсер выполняет анализ следующего документа XML:
В этом случае парсер вызовет следующие обработчики событий синтаксического анализа:
Все приведенные выше функции объявлены в классе QXmlContentHandler. Для простоты мы не стали указывать некоторые аргументы функций startElement и endElement.
QXmlContentHandler — это всего лишь один из многих классов—обработчиков, которые могут использоваться совместно с классом QXmlSimpleReader. Другими такими классами являются QXmlEntityResolver, QXmlDTDHandler, QXmlErrorHandler, QXmlDeclHandler и QXmlLexicalHandler. Эти классы только объявляют чистые виртуальные функции и предоставляют информацию о различных событиях синтаксического анализа. Для большинства приложений вполне достаточно использовать лишь классы QXmlContentHandler и QXmlErrorHandler.
Для удобства Qt также предоставляет класс QXmlDefaultHandler, который наследует все классы—обработчики и обеспечивает очень простую реализацию всех функций. Такая конструкция со множеством абстрактных классов—обработчиков и одним подклассом с тривиальной реализацией функций необычна для Qt; она принята для максимального соответствия модели Java—реализации.
Теперь мы рассмотрим пример, который показывает способы применения QXmlSimpleReader и QXmlDefaultHandler для синтаксического анализа файла XML заранее известного формата и для отображения его содержимого в виджете QTreeWidget. Подкласс QXmlDefaultHandler имеет название SaxHandler, и он используется для обработки предметного указателя книги, который содержит элементы и подэлементы.