Создание GUI в Linux. Часть 2.
АрхивПрограммазм (архив)Продолжение разговора о создании GUI в Linux. Пример использования Qt.
В первой части этой статьи мы говорили о создании графического интерфейса пользователя с помощью библиотеки Gtk. Самым ярким примером использования этой библиотеки является оконная среда Gnome. В этой части статьи мы поговорим о библиотеке Qt. На этой библиотеке была написана всем известная оконная среда KDE.
Существуют две версии Qt – коммерческая и бесплатная, которая входит в состав любого дистрибутива. Чтобы писать программы с использованием Qt нужно установить саму библиотеку (скорее всего, уже будет установлена у вас) и пакет qt-devel, содержащий все необходимые файлы для разработки Qt-программ.
Сейчас мы рассмотрим листинг layout.cpp, который демонстрирует расположение графических примитивов на окне программы. Данный пример является стандартным примером. Архив с примерами вы можете найти в каталоге /usr/share/qt-x-x-x/doc/. x-x-x – это версия вашей библиотеки.
Прежде чем приступить к рассмотрению листинга, напомню, что графические примитивы – кнопки, списки, переключатели и все подобное им называются виджитами – как и в библиотеке Gtk. Обработчики событий, например, обработчик события нажатия кнопки, называются слотами. Точнее, в слот вы можете «вставить» функцию, которая будет обрабатывать то или иное событие.
Вот листинг с детальными комментариями:
/* ** 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