Естественно, из меня писатель как из бутылки молоток, так что уж простите, если
увидети выдержки из какой-либо знакомой вам доселе не обессудте :-)))
И
огромное спасибо uj за оказанную помощь в разработке статьи!!! Респект :-=))
И так... поехали!...
1. Что такое QT?
=================
Qt --
это кроссплатформенная библиотека, целью которой является вытеснение нативных
API из ваших
программ. Сейчас Qt -- это огромный объектно-ориентированный
комбайн, в большинстве случаев
позволяющий обойтись без привлечения
каких-либо иных библиотек.
В первую очередь Qt -- отличное средство для
создания графического пользовательского
интерфейса (GUI). В состав Qt входит
дизайнер, позволяющий легко создавать графические интерфейсы
для вашего
приложения.
Вам не придется заботиться о написании файлов сборки для каждой
из платформ, за вас это сделают Qt.
Достаточно просто написать файл проекта,
в который внести все используемые файлы, и файл
сборки можно будет создать
одним вызовом утилиты qmake (естественно, под управлением целевой
платформы). От себя добавлю, что иногда этот файл приходится править руками
(а как же).
О значимости данной библиотеки говорит хотя бы то, что она
используется в таких успешных проектах,
как Borland C++ Builder 6 и
Opera.
2. Где достать?
================
Библиотека поставляется по
нескольким лицензиям, одни из которых -- платные, другие -- нет. Под
оконную
систему X11 всегда можно с сайта www.trolltech.com легально
взять GPL-версию
Qt (и использовать, естественно, только
в некоммерческих проектах). С
системой Windows дело обстоит сложнее, поскольку, по мнению
верхушки
TrollTech, эта система не является ареной OpenSource-разработки.
Последняя бесплатная версия для
Windows -- 2.3.0. Но для находчивых людей это
не проблема, есть сеть eDonkey ;-) Текущей на данный
момент является версия
3.3.1. В скором времени ожидается версия 4.
3. Технические
подробности
=============================
Изначало Qt "работало" на
пользовательский интерфейс. И именно поэтому эта часть библиотеки
наиболее
используема и наиболее развита. Интересен подход к позиционированию
виджетов (виджет -- элемент
GUI, всё что рисуется на окошке, включая его
само) -- система слоёв (layout) позволяет вам забыть об абсолютном
позиционировании, как о страшном сне. Теперь класс Layout сам следит за тем, что
вы делаете с, например, главным окном и позиционирует все внутренние виджеты
вслед за изменением геометрии этого окошка.
Центральной идеей Qt является
сигнально-слотовый механизм, реализующий взаимосвязь между объектами.
Этот
механизм реализован посредством прекомпиляции, что позволяет использовать его
без всяких
ухищрений (если вы заинтересованы в Qt, прямо в данный момент
забудьте о callback-вызовах ).
Каждый Qt-объект (не только вызуальные
элементы!) может генерировать некоторые сигналы, жестко
зашитые в структуру
его класса. Сигнал -- это функция, объявленная в специальной секции signals
и
не имеющая реализации ("тела") а только передаваемые аргументы. К сигналу
объекта (заметьте, не класса) могут быть подключены слоты. Слот -- это всего
лишь метод, также объявленный в специальных секциях "slots". Слоты
могут быть
доступными (секция "public slots"), защищенными ("protected slots") и
скрытыми ("private slots"). При помощи специального метода connect слот
подсоединяется к сигналу.
Небольшой пример:
connect(myValueDetector, SIGNAL(ValueChange( Value a), myApplicationUpdater, SLOT(onValueChange( Value a ))));
|
После
чего при каждом "испускании" сигнала ValueChange объектом
myValueDetector
будет вызываться слот onValueChange объекта
myApplicationUpdater.
Плюсы -- к одному сигналу можно подключить несколько
слотов.
Минусы -- один слот нельзя использовать для нескольких сигналов
(например, для обработки группы кнопок). Сравните с системой событий VCL/CLX --
там как раз всё наоборот. Рассмотрим небольшой пример использования
сигнально-слотового механизма:
//то, что инициирует сигнал для изменения class aValueDetector:public QObject { Q_OBJECT // нужно для объявления сигналов и слотов public: aValueDetector( Value a ); signals: ValueChange( Value a ); } //то, что его сможет обработать class aApplicationUpdater:public QObject { Q_OBJECT public: aApplicationUpdater(); public slots: onValueChange( Value a ); } // то, что всем управляет class aApplication { public: aApplication() { //некоторый код .................. //а вот теперь самое главное connect(myValueDetector, SIGNAL(ValueChange( Value a )), myApplicationUpdater, SLOT(onValueChange( Value a )))); // причем, заметьте, один сигнал может вызывать и другой сигнал и иметь несколько коннектов // одновременно } protected: aValueDetector* myValueDetector; aApplicationUpdater* myApplicationUpdater; }
|
Как видите, код "немного" отличается от стандартного C++. Данный текст
подаётся на вход мета-компилятора moc, который из него уже производит
стандартный код C++, который затем компилируется любым компилятором. Moc
отличает "свои", т.е. поддерживающие сигнально-слотовый механизм, классы от
стандартных по ключевому слову Q_OBJECT в самом начале объявления
класса.
Перечислим основные достоинства ядра библиотеки Qt:*
встроенная поддержка Unicode и локализации (очень хорошо и очень правильно
реализованной, смею
заметить). В Qt4 обещают новый механизм рендеринга
шрифтов, поддерживающий Unicode.
* мощные события и фильтры событий (событие
- это что-то вроде универсального сигнала, который можно посылать любому
виджету, распознавать и соотвествующим образом обрабатывать с помощью фильтров.
Например нажатие различных клавиш)
* многофункциональные управляемые
интервалами таймеры которые делают возможным просто и быстро
вставлять много
разных заданий в управляемый событиями ГПИ.
* иерархические и настраиваемые
объектные деревья, организующие принадлежность объектов естественным
образом.
* защищенные указатели QGuardedPtr, которые автоматически
принимают значение NULL при
уничтожении соответствующего объекта, в отличие
от обычных указателей в C++, которые в этом
случае становятся
"неопределенными указателями".
* Удобная документация, доступная и на русском
языке (ссылки к сожалению не знаю, но могу с удовольствием выслать по
заявке).
В состав ядра библиотеки входят как классы для построения GUI
(например: метка, поле ввода, кнопка и
т.п.), так и классы, предназначенные
для организации различных струтур хранения данных (например,
списковых),
работы с файлами, сетевого взаимодействия и многого другого. Некоторые из
этих
возможностей реализованы в виде дополнительных модулей:
* модуль
Canvas, мощный инструмент для работы с двухмерной графикой. Он использует
принцип
структурирования графики, что, несомненно, будет полезно в
программировании простых двухмерных
игр и подобного рода вещах. Холст состоит
из нескольких "элементов", каждый элемент представлен
объектом.
Поддерживается также ряд интересных возможностей, таких как collision-detection,
перемещение(нет во фришных версиях под виндой :-((( )
объектов с
определенными скоростями по осям. Подробнее читаем по ссылке:
Ссылка* модуль Network, обеспечивающий поддержку сети в
приложениях.
* модуль OpenGL, позволяющий работать с трехмерной графикой при
помощи портабельной библиотеки
OpenGL. Поддерживается с версии 2.3.2.
*
модуль SQL, реализующий доступ к базам данных из приложений Qt. Данный модуль
разбит на три уровня:
пользовательский (элементы интерфейса), программный
(абстрактный доступ к базам данных) и уровень
драйверов.
* модуль Table,
предоставляющий в ваше распоряжение сетку для отображения табличных данных.
Сетка
являет собой очень мощный и гибкий интерфейс, работать с которым --
одно удобольствие
* модуль XML, использующий интерфейс SAX2 и реализацию DOM
второго уровня.
Это далеко не полный перечень возможностей Qt.
3.
Как написать простенькое приложение на
QT?
=================================================
Напишем файлик
main.cpp следующего содержания:
#include <qapplication.h> #include <qpushbutton.h> int main( int argc, char **argv ) { QApplication a( argc, argv ); // ну понятно, что без аппликухи никуда :-) QPushButton hello( "Привет, Мир!", 0 ); // Создаём простенькую кнопочку hello.resize( 100, 30 ); // растягиваем её, можно при желании и на весь экран :-) a.setMainWidget( &hello ); // Делаем кнопку основным виджетом, это нужно для того, чтобы при закратии этой самой кнопки всё приложение завершило свою работу hello.show(); // это чтобы нашу красоту все увидели :-) return a.exec(); // и как говориться "Поехали" copyright by Y. Gagarin :-) }
|
Теперь
напишем файл проекта под это дело (simple.pro):
PROJECT = simple TEMPLATE = app CONFIG = qt warn_on debug SOURCES = main.cpp TARGET = simple
|
В
командной строке наберем: