Тестирование софта - статьи

       

Как оно работает


Говоря в общем, все вращается вокруг событий, называемых сигналами, и слотов — то есть регистрируемых реакций на эти события. В отличие от других "закрытых" событийных множеств (вроде тех, что встречаются в Active Script) система сигналов Qt полностью динамическая — каждый участок кода может регистрировать или обрабатывать сигналы. Это напоминает механизм, условно известный как WM_USER+1.

Сигналы имеют отдаленное отношение к системным событиям и являются их произвольной трансляцией — так же как это реализовано в Delphi. Естественно, что ни одна система не должна порождать таких шквалов нотификаций, как Windows. Обеспечивать приложению доступ к событиям неклиентской области — по-моему, большая ошибка архитекторов этой системы, породившая немало "смешных" интерфейсов.

Что касается графического интерфейса, то он более всего похож на Java Swing — тут тоже существуют схемы стилей, например Windows, CDE, Motif, копирующие известные оболочки. Присутствуют также layout’ы, автоматически размещающие элементы управления; кроме того, есть такие "пружинки", или "спейсеры", которые расталкивают сопредельные компоненты.

Есть также немало вещей, напоминающих Delphi: хинты размеров (то есть "как было бы лучше"), масштабирование компонент и прочие вещи, претендующие на красивость.

Как и в Swing, все элементы перерисованы от руки, то есть стандартные механизмы рисования элементов управления не применяются — вместо этого используется, например, GDI WinAPI. Автоматически определяется версия ОС и, соответственно, реализуются или игнорируются те или иные свойства, вроде прозрачности или XP-прибамбасов. В качестве небольшого попуска Qt использует стандартные диалоговые окна Windows, в частности диалоги открытия файла и настойки печати.

Под X11 Qt не использует тулкиты вроде Motif или Xt — ну, Qt вроде и сам такой же тулкит (то есть — зачем же?). Вместо этого напрямую используется Xlib — с расширениями вроде RENDER, если они доступны.

Схема "генеральной помпы", то есть основного цикла событий, не очень отличается от всех подобных во всех ОС — от MS Windows до PalmOS.
Приложение строится просто, если не сказать примитивно: создается главное окно, устанавливаются его параметры, после чего приложение непосредственно "ранится". Вот как выглядит известный всем "Привет, мир!": #include < qapplication.h >
#include < qlabel.h >
int main( int argc, char **argv )
{
QApplication app( argc, argv );
   QLabel *hello = new QLabel( "Привет, мир!", 0 );
   app.setMainWidget( hello );
   hello->show();
   return app.exec();
}
Естественно, это вам не Visual Basic: вы можете создавать собственные элементы управления — это, как и в Delphi, поощряется, а не наоборот. Писать их не сложнее, чем дельфийские, а то и проще. Вот, к примеру, как реализуются LCD-часы на основе класса, отрисовывающего LCD-строку: #include < qdatetime.h >
#include "clock.h"
Clock::Clock( QWidget *parent, const char *name )
: QLCDNumber( parent, name ), showingColon( true ) {
   showTime();
   startTimer( 1000 );
}
void Clock::timerEvent( QTimerEvent * ) { showTime(); }
void Clock::showTime() {
   QString time = QTime::currentTime().toString().left( 5 );
   if ( !showingColon ) time[2] = ’ ’;
   display( time );
   showingColon = !showingColon;
}
Не сложно — а если б выключить мигание двух точек, так и вовсе тривиально. Кстати, мне показалось что знак "!" перед showingColon можно "сэкономить" — ну, конечно, заменив для мнемоничности showcolon на hidecolon. Да и showTime() в конструкторе можно бы убрать… Короче, в полном ходу лозунг Trolltech: code_less && create_more — только не стоит вычислять эту выражение по короткой схеме :).

Содержание раздела