Разделитель
    Программирование GUI С QT TROLLTECH Framework  
  26.06.2004 13:31  
Савенко М.А.
Данная статья, и возможно последующие, предлагают познакомить читателя с библиотекой Qt. По моему мнению, программирование интерфейса пользователя с использованием этой библиотеки, является наиболее легким из всех существующих, и использующих язык С++ как язык разработки. Надо отдать должное разработчикам Qt, благодаря их труду каждый элемент интерфейса, его функции(методы), в большинстве своем являются интуитивно понятными, благодаря точному следованию правил именования классов и элегантно выбранным именам, программный интерфейс выглядит очень доступным, лаконичным, а используемая модель сигнал-слот создает изумительный по простоте интерфейс событий между объектами. Важно отметить что программы написанные на Qt являются полностью переносимыми (переносимость определяется платформами, поддерживаемыми Qt). И ко всему прочему компания Trolltech выпускает бесплатные релизы Qt специально для разработки Open Source программного обеспечения под лицензией GNU.

Данная статья дает обзор библиотеки Qt. Получилась она в основном как перевод стандартной документации Qt, которая к сожалению отсутствует на русском языке. Далее мы рассмотрим практический пример – традиционное приложение HelloWorld. Итак...

Qt это много платформенный C++ фрэймворк для разработки приложений с графическим пользовательским интерфейсом (GUI) . Qt предлагает разработчикам приложений всю необходимую функциональность для разработки приложений с самым современным пользовательским интерфейсом. Qt является полностью объектно-ориентированным, легко расширяемым, и предоставляет возможность истинного компонентного программирования. С начала первого коммерческого выхода в начале 1996г. , Qt стало основой многих тысяч удачных приложений по всему миру. Qt так же стало основой популярного оконного менеджера KDE , который в настоящий момент входит в любой современный дистрибутив Linux.

Qt поддерживает следующие платформы:

  • MS/Windows -- 95, 98, NT 4.0, ME, 2000, and XP
  • Unix/X11 -- Linux, Sun Solaris, HP-UX, Compaq Tru64 UNIX, IBM AIX, SGI IRIX и широкий спектр других
  • Macintosh -- Mac OS X
  • Embedded -- Linux платформы с поддержкой фрэмбуфера.

Qt является продуктом фирмы Trolltech, и выходит в следующих изданиях:

  • Qt Enterprise Edition и Qt Professional Edition ориентированы на разработку коммерческого программного обеспечения. Это традиционное коммерческое издание, включающее в себя бесплатный апгрэйд и техническую поддержку. Информацию о стоимости издания можно найти на сайте компании Trolltech, или использовать контакт - sales@trolltech.com. Enterprise Edition предлагает дополнительные модули как дополнение к Professional Edition.
  • Qt Free Edition - Unix/X11 версия Qt доступна только для разработки бесплатного и Open Source программного обеспечения. Это издание является полностью бесплатным и выходит под лицензиями Q Public License и GNU General Public License. Последняя версия этого издания всегда доступна для скачивания на сайте Trolltech.
  • Qt/Embedded Free Edition – “Полносвободное” издание для разработки полностью свободного программного обеспечения. Это издание так же является бесплатным и доступным для скачиваия. Выходит под лицензией GNU General Public License.

Qt имеет модульную структуру, после инсталляции Qt, модули компонуются в библиотеку. Для Qt Enterprise Edition, Qt Evaluation Edition и для Qt Free Edition – это все имеющиеся модули. В Qt Professional Edition, доступными модулями являются: tools, kernel, widgets, dialog, iconview, и workspace. В настоящий момент Trolltech не предлагает модули по отдельности. Все модули выходят под лицензией, под которой выходит издание в который входят эти модули.

Рассмотрим основные модули...

Canvas

Canvas предлагает высоко оптимизированную 2D графическую область называемую QСanvas. Canvas может содержать многочисленное количество элементов - QСanvasItems. Каждый из этих элементов имеют свои собственные размеры, форму и содержание. Они могут свободно передвигаться и легко проверяться на столкновение с другими объектами. Элементы могут перемещаться программно и быть анимироваными с использованием класса QCanvasSprite. (Если вам понадобятся возможности 3D графики см. модуль Qt OpenGL).

Модуль Canvas использует архитектуру документ/вид. QCanvasView используется для отображения Canvas или его части. Возможна организация множества видов одного и того же Canvas одновременно. При этом каждый вид может иметь свою собственную матрицу преобразований, что позволяет легко придать любому из видов дополнительную особенность, например масштабирование.

QCanvas

IconView

Модуль IconView предлагает мощный процесс визуализации графических элементов, объектов(widgets) оформленный классом QIconView. API этого модуля подобны объектам QlistView и QlistBox. Он позволяет хранить/отображать рисунки с текстом, которые пользователь может выбирать, перетаскивать, переименовывать, удалять и выполнять другие операции.

QIconView

Network Module

Network Module предлагает классы для обеспечения легкой, разработки сетевого программного обеспечения, при этом делая его переносимым на другие платформы поддерживаемые Qt. Основными классами этого модуля являются низкоуровневые классы, такие как QSocket, QServerSocket, Qdns и др. которые позволяют работать, обеспечивая переносимость, с сокетами стека протоколов TCP/IP. В дополнение в Qt существуют такие классы как QNetworkProtocol, QNetworkOperation которые предлагают абстрактный уровень представления сетевых протоколов, и QUrlOperator который работает на таких сетевых протоколах. Наконец третьей прослойкой является набор специфических классов относящихся к прикладной области, например QUrl и QUrlInfo которые выполняют разбор URL и др.

OpenGL

OpenGL это стандартное API для рендеринга 3D графики.

OpenGL имеет дело только с 3D рендерингом и обеспечивает лишь небольшую поддержку GUI. Пользовательский интерфейс для приложений OpenGL должен создаваться другими средствами, например такими как Motif на платформе X, Microsoft Foundation Classes (MFC) для Windows, или Qt на обоих платформах сразу.

Модуль Qt OpenGL облегчает использование OpenGl в приложениях Qt. Он предлагает widget класс который может использоваться как любой другой Qt widget, за исключением того что он может открывать дисплейный буфер, где можно использовать OpenGL API для рендеринга его содержимого.

Qt OpenGL модуль выполнен как платформ но независимый Qt/C++ врапер(оболочка) вокруг платфорно независимых библиотек GLX, WGL, или AGL C APIs. Предлагаемая функциональность модуля подобна библиотеки Mark Kilgard's GLUT, но со значительно большей GUI (не OpenGL) функциональностью, т.е. Полной поддержкой Qt API.

Qt SQL

Модуль Qt SQL состоит из набора классов, которые разделены на три группы(слоя):

  • Интерфейс пользователя. Эти классы образуют видгеты, которые могут подключаться к таблицам или видам в базе данных (посредством использования QSqlCursor в качестве датасорса). Конечные пользователи могут непосредственно взаимодействовать с этими видгетами для просмотра или изменения их содержимого. В QtDesigner входят все SQL классы и поэтому он может быть использован для создания форм представления данных. Видгеты могут программироваться и напрямую, с вашим собственным С++ кодом. Набор классов входящих в этот слой включает QSqlEditorFactory, QSqlForm, QSqlPropertyMap, QDataTable, QDataBrowser и QDataView.
  • SQL API Layer. Эти классы обеспечивают доступ к базам данных. Соединения с базами данных создаются при помощи класса QSqlDatabase. Взаимодействие с базой данных происходит посредством использования класса QSqlQuery который позволяет выполнять команды SQL напрямую или посредством класса более высокого уровня QSqlCursor, который строит SQL команду автоматически. В дополнение к QSqlDatabase, QSqlCursor и QSqlQuery, SQL API layer предлагает классы QSqlError, QSqlField, QSqlFieldInfo, QSqlIndex, QSqlRecord и QSqlRecordInfo.
  • Driver Layer. Этот слой заключен в виде классов QSqlResult, QSqlDriver и QSqlDriverFactoryInterface. Этот слой предлагает низкоуровневый мост между базами данных и классами SQL. Этот слой больше отнесен к разработчикам драйверов.

Table

Модуль Table предлагает гибкий и изменяемый табличный видгет - QTable. Многие приложения могут использовать QTable просто напрямую, формируя грид(сетку) с ячейками доступными для программирования. QTable так же может наследоваться подклассами для организации огромных таблиц например миллион на миллион ячеек...

QTable

Workspace

Модуль предлагает рабочее окно, которое может содержать окна документов для обеспечения архитектуры Multiple Document Interfaces (MDI).

Этот модуль представлен одним единственным классом – Qworkspace.

XML

Модуль XML предлагает хорошо оформленный XML парсер использующий SAX2 (Simple API for XML) интерфейс плюс исполнение DOM Level 2 (Document Object Model).

SAX это стандартный интерфейс XML парсера, основанный на событиях. Интерфейс Qt следует дизайну SAX2 Java implementation. Его naming scheme была адаптирована для поддержки соглашений об именовании в Qt. Больше информации по SAX2 может быть найдено на сайте http://www.megginson.com/SAX/.

Поддержка фильтров SAX2 и reader factory находятся в разработке. Qt не включает совместимость с классами SAX1 присутствующими в Java интерфейсе.

В других статьях мы еще будем обращаться к документации Qt, а пока перейдем к практике.

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

Как и любая программа написанная на языке С/С++, приложение Qt имеет в качестве стартовой точки процедуру main() (см. листинг main.cpp). Давайте рассмотрим эту процедуру подробно. Первая строчка создает объект класса QApplication:

QApplication a(argc, argv);

Класс QApplication создает управляющий объект всего приложения (управление событиями, реакциями и др.) а так же производит основные настройки всего приложения. В качестве параметров передаются параметры командной строки, помимо пользовательских аргументов, класс QApplication может различать специфичные для него параметры, например:

  • -style=style, устанавливает стиль GUI. Возможными значениями могут быть - motif, windows, и platinum. Если вы скомпилировали Qt с поддержкой дополнительных стилей, или у вас есть дополнительные стили в виде плагинов, они будут так же доступны через эту опцию.
  • -session=session, восстанавливает приложение из ранних его сессий.

О других опции командной строки вы можете почитать в документации Qt по классу QApplication.

В следующей строчке:

a.setFont(QFont("helvetica", 12));

производится настройка приложения на шрифт используемый по умолчанию для всего приложения. Каждый графический элемент в последствии может для себя изменить его, но по умолчанию для него будет использоваться именно этот шрифт.

Qt предлагает отличные средства интернационализации (i18) написанных с использованием Qt. Далее в программе производятся действия по настройке локализации:

QTranslator tor( 0 );

// set the location where your .qm files are in load() below as the last parameter instead of "."
// for development, use "/" to use the english original as
// .qm files are stored in the base project directory.
tor.load( QString("helloworld.") + QTextCodec::locale(), "." );
a.installTranslator( &tor );

Тема интернационализации будет рассмотрена в следующей статье, поэтому обсуждать эти строчки здесь мы не будем.

Далее комментарий показывает, что вы можете установить стиль отображения элементов вашего приложения если стиль по умолчанию вас не будет устраивать:

/* uncomment the following line, if you want a Windows 95 look*/
// a.setStyle(WindowsStyle);

Следующим базовым элементом приложения Qt является главное окно, которое описывает класс QMainWindow. Класс QMainWindow служит для построения главного окна приложения с меню, панелями инструментов и статусбаром.

Таким образом здесь мы должны создать объект главного окна – HelloWorld(реализацию этого класса мы рассмотрим далее) и назначить его как главное для нашего приложения, это выглядит следующим образом:

HelloWorldApp *helloworld=new HelloWorldApp();
a.setMainWidget(helloworld);

Метод QApplication setMainWidget, связывает объект приложения с объектом главного окна, назначая второй первому.

Главная программа завершается строчкой

return a.exec();

Вызывается метод класса QApplication exec() и при выходе из приложения код возврата этого метода передается операционной системе. Метод exec организует главный цикл приложения, который работает до тех пор, пока не будет вызвана функция exit() или пока не будет разрушен главный видгет приложения, а возвращаемое exec значение будет кодом переданным в функции exit(). Документация Qt отмечает важность этой функции, объясняя что весь поток обработки событий проходит через этот цикл. Главный цикл получает события от оконной системы и доставляет их видгетам приложения. Вообще, как говориться в документации Qt, никакого взаимодействия с пользователем не будет, пока не будет вызвана функция exec. Существуют особые случаи, где вышесказанное не верно, это касается модальных видгетов, таких как QmessageBox, которые могут быть вызваны, до вызова функции exec() и работать нормально, т.к. модальные видгеты создают свой локальный цикл сообщений, посредством своего собственного вызова exec().

Теперь давайте рассмотрим реализацию класса главного окна приложения – HelloWorldApp.

Посмотрим на объявление класса (см. листинг helloworld.h):

class HelloWorldApp : public QMainWindow {
Q_OBJECT

public:
class=code_comment>/** construtor */
HelloWorldApp();
class=code_comment>/** destructor */
~HelloWorldApp();
};

Чтобы создать свой класс главного окна, необходимо унаследовать его от класса QMainWindow, что мы и сделали. При этом класс содержит только конструктор и деструктор. Здесь наиболее важным моментом является вставка макроса Q_OBJECT, которая определяет этот объект как использующий схему сигнал-слот, для взаимодействия с другими объектами. Систему сигнал-слот мы будем подробно рассматривать в других статьях.

Реализация конструктора и деструктора достаточно проста (см. листинг helloworld.cpp):

HelloWorldApp::HelloWorldApp() {
  setCaption(tr("HelloWorld"));
}
HelloWorldApp::~HelloWorldApp() {
}

В конструкторе, функцией setCaption мы определяем строку, которая будет отображаться в заголовке окна. Макрос tr() относится к вопросу интернационализации, и поэтому здесь о нем говорить не будем, важно, что если интернационализация вам не нужна, просто не используйте его, в нашем примере, мы могли бы написать так:

setCaption("HelloWorld");

Собтвенно мы написали первое Qt приложение, осталось его скомпилировать и посмотреть на результаты нашего труда.

Qt предоставляет утилиту qmake, аналогичную утилите make, но имеющую множество дополнительных полезных функций, ориентированных на помощь в сборке приложений Qt.

qmake позволяет на основе указанной информации об имеющихся исходных файлах проекта построить полноценный Makefile, через который мы и будем создавать исполняемый файл нашего проекта. Информация о проекте передается утилите qmake через файл с расширением pro. Создадим файл helloworld.pro. В файле необходимо указать несколько констант, CONFIG, SOURCES, HEADERS, TARGET. В нашем файле helloworld.pro:

CONFIG=qt
HEADERS=helloworld.h
SOURCES=helloworld.cpp
SOURCES+=main.cpp
TARGET=helloworld

Переменная CONFIG указывает qmake, что при сборке приложения надо подключать библиотеку Qt. Переменная HEADERS содержит все заголовочные файлы приложения, а SOURCES все исходные файлы. Переменная TARGET определяет имя которое будет иметь исполняемый файл после сборки.
Итак помещаем файл helloworld.pro в каталог нашего проекта, и выполняем команду qmake:

[maxix@home maxix]$ cd ~/src/helloworld
[maxix@home helloworld]$ qmake

Теперь в нашем каталоге появился файл Makefile. Теперь все что нам нужно, это выполнить стандартную операцию сборки приложения, т.е. Выполнить команду make находясь в директории нашего проекта. После сборки и запуска приложения мы увидим следующее:

Hello World

Исходные файлы нашего проекта можно скачать здесь.

Источник: http://www.itx.ru/