Создание GUI в Linux. Часть 2.

Денис Колисниченко

В первой части этой статьи мы говорили о создании графического интерфейса пользователя с помощью библиотеки 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


Linux coutner
Hosted by uCoz