Денис Колисниченко
В первой части этой статьи мы говорили о создании графического интерфейса пользователя с помощью библиотеки Gtk. Самым ярким примером использования этой библиотеки является оконная среда Gnome. В этой части статьи мы поговорим о библиотеке Qt. На этой библиотеке была написана всем известная оконная среда KDE.
Существуют две версии Qt - коммерческая и бесплатная, которая входит в состав любого дистрибутива. Чтобы писать программы с использованием Qt нужно установить саму библиотеку (скорее всего, уже будет установлена у вас) и пакет qt-devel, содержащий все необходимые файлы для разработки Qt-программ.
Сейчас мы рассмотрим листинг layout.cpp, который демонстрирует расположение графических примитивов на окне программы. Данный пример является стандартным примером. Архив с примерами вы можете найти в каталоге /usr/share/qt-x-x-x/doc/. x-x-x - это версия вашей библиотеки.
Прежде чем приступить к рассмотрению листинга, напомню, что графические примитивы - кнопки, списки, переключатели и все подобное им называются виджитами - как и в библиотеке Gtk. Обработчики событий, например, обработчик события нажатия кнопки, называются слотами. Точнее, в слот вы можете "вставить" функцию, которая будет обрабатывать то или иное событие.
Вот листинг с детальными комментариями:
Создание GUI в Linux. Часть 2.
/*
** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
**
**
*/
#include <qapplication.h>
#include <qlabel.h>
#include <qcolor.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qmultilineedit.h>
#include <qmenubar.h>
#include <qpopupmenu.h>
/* Объявление класса ExampleWidgit - этот класс и будет нашим виджитом -
как кнопка или поле ввода
*/
class ExampleWidget : public QWidget
{
public:
// конструктор
ExampleWidget( QWidget *parent = 0, const char *name = 0 );
// деструктор
~ExampleWidget();
};
ExampleWidget::ExampleWidget( QWidget *parent, const char *name )
: QWidget( parent, name )
{
// Вертикальный бокс будет содержать все виджиты
QBoxLayout *topLayout = new QVBoxLayout( this, 5 );
// Создаем меню
QMenuBar *menubar = new QMenuBar( this );
menubar->setSeparator( QMenuBar::InWindowsStyle );
QPopupMenu* popup;
popup = new QPopupMenu( this );
// Определяем обработчик события - слот для команды Quit
popup->insertItem( "&Quit", qApp, SLOT(quit()) );
menubar->insertItem( "&File", popup );
// Указываем расположение меню
topLayout->setMenuBar( menubar );
// Создаем горизонтальный блок и заполняем его кнопками
QBoxLayout *buttons = new QHBoxLayout( topLayout );
int i;
for ( i = 1; i <= 4; i++ ) {
// Новая кнопка
QPushButton* but = new QPushButton( this );
// Надпись
QString s;
s.sprintf( "Button %d", i );
but->setText( s );
// Растяжение по горизонтали - 10. Фактор растяжения позволяет
// кнопкам растягиваться по горизонтали. Другими словами - это расстояние
// между кнопками по горизонтали.
buttons->addWidget( but, 10 );
}
// Создаем второй гор. бокс, содержащий кнопки, выровненные по левому краю
QBoxLayout *buttons2 = new QHBoxLayout( topLayout );
// Кнопка с надписью Button five
QPushButton* but = new QPushButton( "Button five", this );
buttons2->addWidget( but );
// Кнопка с надписью Button 6
but = new QPushButton( "Button 6", this );
buttons2->addWidget( but );
buttons2->addStretch( 10 );
// Создаем большой виджит (поле для ввода текста - аналог компонента
// TMemo в Delphi), который займет все место в центре окна
QMultiLineEdit *bigWidget = new QMultiLineEdit( this );
bigWidget->setText( "This widget will get all the remaining space" );
bigWidget->setFrameStyle( QFrame::Panel | QFrame::Plain );
// Добавляем виджит в бокс topLayout
topLayout->addWidget( bigWidget );
// Создаем таблицу, содержащую надписи и поля ввода
const int numRows = 3;
const int labelCol = 0;
const int linedCol = 1;
const int multiCol = 2;
// Расстояние между виджитами - 10 px
QGridLayout *grid = new QGridLayout( topLayout, 0, 0, 10 );
int row;
for ( row = 0; row < numRows; row++ ) {
QLineEdit *ed = new QLineEdit( this );
// Поля ввода будут помещены во вторую колонку
grid->addWidget( ed, row, linedCol );
// Создание надписи
QString s;
s.sprintf( "Line &%d", row+1 );
QLabel *label = new QLabel( ed, s, this );
// Надписи будут помещены в первую колонку таблицы
grid->addWidget( label, row, labelCol );
}
// Еще один аналог TMemo (в Qt он называется multiline edit)
// Он будет занимать ряды таблицы от 0 до numRows, оставаясь при этом во
// второй колонке
QMultiLineEdit *med = new QMultiLineEdit( this );
grid->addMultiCellWidget( med, 0, -1, multiCol, multiCol );
// Расстояние между колонками
grid->setColStretch( linedCol, 10 );
grid->setColStretch( multiCol, 20 );
// Небольшая панель внизу окна
QLabel* sb = new QLabel( this );
sb->setText( "Let's pretend this is a status bar" );
sb->setFrameStyle( QFrame::Panel | QFrame::Sunken );
// Этот виджит займет все горизонтальное пространство, но будет
// иметь фиксированную высоту
sb->setFixedHeight( sb->sizeHint().height() );
sb->setAlignment( AlignVCenter | AlignLeft );
topLayout->addWidget( sb );
// Активизация бокса
topLayout->activate();
}
ExampleWidget::~ExampleWidget()
{
// Все виджиты удаляются Qt, поэтому деструктор пуст
}
int main( int argc, char **argv )
{
// Создаем Qt-приложение
QApplication a( argc, argv );
// Объявляем нам виджит
ExampleWidget f;
// Он должен быть главным виджитом окна
a.setMainWidget(&f);
// Заголовок окна
f.setCaption("Qt Example - Caption");
// Показываем наш шедевр
f.show();
return a.exec();
}
Обратите внимание, что в отличие от Gtk, библиотека Qt использует объектно-ориентированный подход, поэтому файлы программ должны заканчиваться на .cpp или на .cc (ну нет в Linux термина "расширение" :)) ). Для сборки программы введите команду:
#~/bin/bash gcc layout.cpp -o layout -I/usr/lib/qt3/include -I/usr/X11R6/include -L/usr/X11R6/lib -L/usr/lib/qt3/lib -lqt
В результате будет создан исполнимый файл layout, запустив который вы увидите следующее:
Более подробно о работе с виджитами и библиотеке Qt вы сможете прочитать в документации по библиотеке, которую вы найдете в каталоге /usr/share/doc/qt-3.0.4/doc/html.
Ваши вопросы и комментарии рад буду выслушать по адресу dhsilabs@mail.ru