Текст книги "Основы программирования в Linux"
Автор книги: Нейл Мэтью
Соавторы: Ричард Стоунс
Жанры:
Программирование
,сообщить о нарушении
Текущая страница: 64 (всего у книги 67 страниц)
Списки и деревья в комплекте Qt формируются виджетом QListView
. Этот виджет представляет как простые списки, так и иерархические данные, разделенные на строки и столбцы. Он очень подходит для вывода структур каталогов или чего-то подобного, потому что дочерние элементы можно раскрыть и свернуть, щелкнув кнопкой мыши знак «плюс» или «минус», так же как в файловом обозревателе.
В отличие от виджета GTK+ ListView
виджет QListView
обрабатывает и данные, и их представление, что сделано для облегчения использования, если не для исключительной гибкости.
В виджете QListView
можно выбрать строки или отдельные ячейки и затем вырезать и вставить данные, отсортировать их по столбцу и вы получите виджеты QCheckBox
, отображенные в ячейках. В этот виджет встроено множество функциональных возможностей – как программисту вам достаточно лишь вставить данные и задать некоторые правила форматирования.
Создается виджет QListView
обычным образом, заданием родительского виджета и собственного имени виджета:
QListView *view = new QListView(parent, «name»);
Для задания заголовков столбцов используйте соответствующим образом названный метод addColumn
:
view->addColumn(«Left Column», width1); // фиксированной ширины
view->addColumn(«Right Column»); // с автоматически задаваемым размером
Ширина столбца задается в пикселах или, если пропущена, приравнивается к величине самого длинного элемента в столбце. В дальнейшем при вставке и удалении элементов ширина столбца автоматически меняется.
Данные вставляются в QListView
с помощью объекта QListViewItem
, представляющего строку данных. Вы должны лишь передать в конструктор объект QListView
и элементы строки, и она добавится в конец представления:
QListViewItem *toplevel = new QListViewItem(view, «Left Data», «Right Data»);
Первый параметр – либо объект QListView
, как в данном случае, либо еще один объект типа QListViewItem
. Если передается QListViewItem
, строка создается как дочерняя по отношению к этому объекту QListViewItem
. Таким образом, структура дерева формируется передачей объекта QListView
для узлов верхнего уровня и затем последующих объектов типа QListViewItem
для дочерних или подчиненных узлов.
Остальные параметры – данные каждого столбца, по умолчанию равные NULL
, если не заданы.
Добавление дочернего узла – это просто вариант передачи в функцию указателя верхнего уровня. Если вы не добавляете последующие дочерние узлы в объект QListViewItem
, нет необходимости сохранять возвращаемый указатель:
new QListViewItem(toplevel, «Left Data», «Right Data»);
// Дочерний по отношению к верхнему уровню
В API QListViewItem
можно найти методы обхода узлов дерева на случай корректировки конкретных строк:
#include
virtual void insertItem(QListviewitem* newChild);
virtual void setText(int column, const QString& text);
virtual QString text(int column) const;
QListViewItem* firstChild() const;
QListViewItem* nextSibling() const;
QListViewItem* parent() const;
QListViewItem* itemAbove();
QListViewItem *itemBelow();
Получить первую строку в дереве можно, вызвав метод firstChild
для самого объекта QListView
. Затем можно многократно вызывать firstChild
и nextSibling
для возврата фрагментов или целого дерева.
Приведенный далее фрагмент программного кода выводит первый столбец всех узлов верхнего уровня:
QListViewItem *child = view->firstChild();
while(child) {
cout << myChild->text(1) << «n»;
myChild = myChild->nextSibling();
}
Все подробности, касающиеся QListView
, QListViewItem
и QCheckListView
, см. в документации API комплекта Qt.
Выполните упражнение 17.7.
Упражнение 17.7 Виджет QListView
В этом упражнении вы соберете все вместе и напишете короткий пример использования виджета QListView.
Давайте для краткости пропустим заголовочный файл и рассмотрим реализацию класса, файл ListView.cpp.
#include «Listview.moc»
ListView::ListView(QWidget *parent, const char *name) :
QMainWindow(parent, name) {
listview = new QListView(this, «listview1»);
listview->addColumn(«Artist»);
listview->addColumn(«Title»);
listview->addColumn(«Catalogue»);
listview->setRootIsDecorated(TRUE);
QListViewItem* toplevel = new QListViewItem(listview, «Avril Lavigne»,
«Let Go», «AVCD01»);
new QListViewItem(toplevel, «Complicated»);
new QListViewItem(toplevel, «Sk8er Boi»);
setCentralWidget(listview);
}
int main(int argc, char **argv) {
QApplication app(argc, argv);
ListView *window = new ListView();
app.setMainWidget(window);
window->show();
return app.exec();
}
Как это работает
Виджет QListView
кажется сложным, потому что он действует и как список элементов, и как дерево элементов. В вашем программном коде необходимо создать экземпляры QListViewItem
для каждого элемента, включаемого вами в список. У каждого экземпляра типа QListViewItem
есть родитель. Эти элементы с самим виджетом в качестве родителя отображаются как элементы верхнего уровня. Элементы с другим элементом типа QListViewItem
в качестве родителя выводятся на экран как дочерние элементы. В этом примере показаны экземпляры QListViewItem
со всего одним уровнем глубины, но можно создавать и деревья элементов с гораздо большей глубиной.
После компиляции и выполнения примера ListView вы увидите виджет QListView
в действии, как показано на рис. 17.7.
Обратите внимание на то, как дочерние строки почтительно отступают от своих "родителей". Знаки "плюс" и "минус", указывающие на наличие скрытых или сворачивающихся строк, не представлены по умолчанию; в этом примере они задаются с помощью setRootIsDecorated
.
Рис. 17.7
Диалоговые окна
До сих пор вы создавали подклассы QMainWindow
для построения своих интерфейсов. Объекты QMainWindow
предназначены для создания главного окна в вашем приложении, но для кратковременных диалоговых окон следует рассмотреть виджет QDialog
.
Диалоговые окна хороши для ввода пользователем определенной информации, предназначенной для конкретной задачи, или передачи пользователю коротких сообщений, таких как предупреждение или сообщение об ошибке. Для таких задач лучше применять подкласс QDialog
, поскольку вы получаете удобные методы формирования диалогового окна и специализированные сигналы и слоты для обработки ответов пользователя.
Наряду с обычными модальными и немодальными (или безмодальными на языке Qt) диалоговыми окнами комплект Qt также предлагает полумодальное диалоговое окно. В следующем перечне приведены отличия модальных и немодальных диалоговых окон, в него также включены полумодальные окна.
□ Модальное диалоговое окно блокирует ввод во все другие окна, чтобы заставить пользователя дать ответ в диалоговом окне. Модальные диалоговые окна полезны для захвата немедленного ответа пользователя и отображения важных сообщений об ошибках.
□ Немодальное диалоговое окно – неблокирующее окно, которое действует обычно наряду с другими окнами приложения. Немодальные диалоговые окна удобны для окон поиска или ввода, в которых вы сможете, например, копировать и вставлять значения в главное окно и из него.
□ Полумодальное диалоговое окно – это модальное окно, не имеющее своего цикла событий. Это позволяет возвращать управление приложению, но сохранять блокировку ввода для других окон. Полумодальные окна бывают полезны в редких случаях, когда у вас есть индикатор выполнения процесса важной, требующей значительного времени операции, и вы хотите дать пользователю возможность отменить ее при необходимости. Поскольку у такого окна нет собственного цикла событий, для его обновления вы должны периодически вызывать метод QApplication::processEvents
.
QDialog
– базовый класс диалоговых окон в Qt, предоставляющий методы exec
и show
для обработки модальных и немодальных диалоговых окон, у него есть встроенный класс QLayout
, который можно использовать, и несколько сигналов и слотов, полезных для формирования откликов на нажатие кнопки.
Обычно вы будете создавать для своих диалоговых окон класс-потомок QDialog
и вставлять в него виджеты для создания интерфейса диалогового окна:
#include
MyDialog::MyDialog(QWidget *parent, const char *name) : QDialog(parent, name) {
QHBoxLayout *hbox = new QHBoxLayout(this);
hbox->addWidget(new Qlabel(«Enter your name»));
hbox->addWidget(new QLineEdit());
hbox->addWidget(ok_pushbutton);
hbox->addWidget(cancel_pushbutton);
connect(ok_pushbutton, SIGNAL(clicked()), this, SLOT(accept()));
connect(cancel_pushbutton, SIGNAL(clicked()), this, SLOT(reject()));
}
В отличие от виджета типа QMainWindow
вы можете задать объект MyDialog
как родительский для своего объекта QLayout
без создания пустого QWidget
в качестве родительского.
Примечание
Имейте в виду, что в этом примере пропущен программный код для создания виджетов
ok_pushbutton
иcancel_pushbutton
.
У объекта QDialog
есть два слота – accept
и reject
, которые применяются для обозначения результата, полученного в диалоговом окне. Этот результат возвращается методом exec. Как правило, вы будете связывать кнопки OK и Cancel со слотами, как в MyDialog
.
Модальные диалоговые окна
Для применения диалогового окна как модального вы вызываете метод exec
, который открывает диалоговое окно и возвращает QDialog::Accepted
или QDialog::Rejected
в зависимости от того, какой слот был активизирован:
MyDialog* dialog = new MyDialog(this, «mydialog»);
if (dialog->exec() == QDialog::Accepted) {
// Пользователь щелкнул мышью кнопку OK
doSomething();
} else {
// Пользователь щелкнул мышью кнопку Cancel или
// диалоговое окно уничтожено
doSomethingElse();
}
delete dialog;
Когда метод exec
возвращает управление приложению, диалоговое окно автоматически скрывается, но вы все равно удаляете объект из памяти.
Учтите, что когда вызывается exec
, вся обработка прекращается, поэтому, если в вашем приложении есть важный с точки зрения затраченного времени программный код, больше подойдут немодальное или полумодальное диалоговые окна.
Немодальные диалоговые окна
Немодальные диалоговые окна слегка отличаются от обычных основных окон прежде всего тем, что располагаются поверх своего родительского окна, совместно используют их элемент на панели задач и автоматически скрываются, когда вызван слот accept
или reject
.
Для отображения немодального диалогового окна вызывайте метод show
, как вы сделали бы для окна QMainWindow
:
MyDialog *dialog = new MyDialog(this, «mydialog»);
dialog->show();
Функция show
выводит диалоговое окно на экран и немедленно возвращается в приложение для продолжения цикла выполнения. Для обработки нажатой кнопки вы должны написать слоты и установить с ними связь:
MyDialog::MyDialog(QWidget *parent, const char *name) :
QDialog(parent, name) {
...
connect(ok_pushbutton, SIGNAL(clicked()), this, SLOT(OkClicked()));
connect(cancel_pushbutton, SIGNAL(clicked()), this, SLOT(CancelClicked()));
}
MyDialog::OkClicked() {
// Выполните что-либо
}
MyDialog::CancelClicked() {
// Выполните что-либо другое
}
Как и в случае модального окна, диалоговое окно автоматически скрывается при нажатии кнопки.
Полумодальное диалоговое окно
Для создания полумодального диалогового окна вы должны задать флаг модального режима в конструкторе QDialog
и применить метод show
:
QDialog(QWidget *parent=0, const char *name=0, bool modal=FALSE, WFlags f=0);
Вы не задаете в модальном диалоговом окне флаг модального режима равным TRUE
, потому что вызов exec
заставляет диалоговое окно перейти в модальный режим независимо от значения этого флага.
Конструктор вашего диалогового окна будет выглядеть примерно следующим образом:
MySMDialog::MySMDialog(QWidget *parent, const char *name):
QDialog(parent, name, TRUE) {
...
}
После того как вы определили ваше диалоговое окно, вызовите функцию show
как обычно и затем продолжите свою обработку, периодически вызывая QApplication::processEvents
для обновления вашего диалогового окна:
MySMDialog *dialog = MySMDialog(this, «semimodal»);
dialog->show();
while (processing) {
doSomeProcessing();
app->processEvents();
if (dialog->wasCancelled()) break;
}
Перед продолжением выполнения проверьте, не уничтожено ли диалоговое окно. Имейте в виду, что функция wasCancelled
не является частью класса QDialog
– вы должны написать ее самостоятельно.
Комплект Qt предоставляет готовые подклассы класса QDialog
, предназначенные для конкретных задач, таких как выбор файлов, ввод текста, индикация процесса выполнения и вывод окна сообщения. Применение этих виджетов в любых приложениях убережет вас от множества неприятностей и проблем.
QMessageBox
– модальное диалоговое окно, отображающее простое сообщение с пиктограммой и кнопками. Пиктограмма зависит от серьезности сообщения, которое может содержать обычные сведения или предупреждения и другую важную информацию.
У класса QMessageBox
есть статические методы создания и отображения окон всех трех перечисленных типов:
#include
int information(QWidget *parent, const QString& caption,
const QString&text, int button0, int button1=0, int button2=0);
int warning(QWidget *parent, const QString& caption,
const QString& text, int button0, int button1, int button2=0);
int critical(QWidget *parent, const QString& caption,
const QString& text, int button0, int button1, int button2=0);
Можно выбрать кнопки из списка готовых кнопок QMessageBox
, соответствующих значениям, возвращаемым статическими методами:
□ QMessageBox::Ok
;
□ QMessageBox::Cancel
;
□ QMessageBox::Yes
;
□ QMessageBox::No
;
□ QMessageBox::Abort
;
□ QMessageBox::Retry
;
□ QMessageBox::Ignore
.
Типичный пример использования окна QMessageBox
будет похож на приведенный далее фрагмент программного кода:
int result = QMessageBox::information(this,
«Engine Room Query»,
«Do you wish to engage the HyperDrive?»,
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape);
switch (result) {
case QMessageBox::Yes:
hyperdrive->engage();
break;
case QMessageBox::No:
// сделайте что-нибудь еще
break;
}
Вы соединили операцией OR
(|
) коды кнопок с вариантами Default
и Escape
, чтобы задать стандартные действия, при нажатии клавиш
Рис. 17.8
QInputDialogОкно QInputDialog
полезно для ввода пользователем отдельных значений, будь то текст, вариант раскрывающегося списка, целочисленное или действительное значение. У класса QInputDialog
есть статические методы, например QMessageBox
, создающие некоторые проблемы, поскольку у них слишком много параметров, к счастью, у большинства из них есть значения по умолчанию:
#include
QString getText(const QString& caption, const QString& label,
QLineEdit::EchoMode mode=QLineEdit::Normal,
const QString& text=QString::null,
bool* ok = 0, QWidget* parent = 0, const char * name = 0);
QString getItem(const QString& caption, const QString& label,
const QStringList& list, int current=0, bool editable=TRUE,
bool* ok=0, QWidget* parent = 0, const char* name=0)
int getInteger(const QString& caption, const QString& label,
int num=0, int from = -2147483647, int to = 2147483647,
int step = 1, bool* ok = 0, QWidget* parent = 0, const char* name = 0);
double getDouble(const QString& caption, const QString& label,
double num = 0, double from = -2147483647, double to = 2147483647,
int decimals = 1, bool* ok = 0, QWidget* parent = 0, const char* name = 0);
Для ввода строки текста напишите следующий фрагмент кода:
bool result;
QString text = QInputDialog::getText(«Question», «What is your Quest?:»,
QLineEdit::Normal, QString::null, &result, this, «input»);
if (result) {
doSomething(text);
} else {
// Пользователь нажал Cancel
}
Как видно из рис. 17.9, окно QInputDialog
создано с помощью виджета QLin
eEdit и кнопок OK и Cancel.
Рис. 17.9
Диалоговое окно, созданное методом QInputDialog::getText
, применяет виджет QLineEdit
. Параметр режима редактирования, передаваемый в функцию getText
, управляет способом отображения набираемого текста точно так же, как аналогичный параметр режима виджета QLineEdit
. Вы можете также задать текст, выводимый по умолчанию, или оставить поле пустым, как показано на рис. 17.9. У всех окон QInputDialog
есть кнопки OK и Cancel, и в метод передается указатель типа bool
для обозначения нажатой кнопки – результат равен TRUE
, если пользователь щелкает мышью кнопку OK.
Метод getItem
с помощью раскрывающегося списка QComboBox
предлагает пользователю список вариантов:
bool result;
QStringList options;
options << «London» << «New York» << «Paris»;
QString city = QInputDialog::getItem(«Holiday», "Please select a
destination:", options, 1, TRUE, &result, this, «combo»);
if (result) selectDestination(city);
Созданное диалоговое окно показано на рис. 17.10.
Рис. 17.10
Функции getInteger
и getDouble
действуют во многом аналогично, поэтому мы не будем на них останавливаться.
Компиляция приложения с библиотеками KDE и Qt становится утомительным занятием, поскольку ваш make-файл получается очень сложным из-за необходимости использовать moc
и иметь библиотеки здесь, там и везде. К счастью, Qt поставляется с утилитой qmake
для создания ваших make-файлов.
Примечание
Если вы уже пользовались комплектом Qt, вам, возможно, знакома утилита
tmake
– более раннее (и теперь устаревшее) воплощениеqmake
, поставлявшееся с предыдущими версиями Qt.
Утилита qmake
принимает в качестве входного файл .pro. Этот файл содержит самые существенные сведения, необходимые для компиляции, такие как исходные тексты, заголовочные файлы, результирующий двоичный файл и местонахождения библиотек KDE/Qt.
Типичный pro-файл среды KDE выглядит следующим образом:
TARGET = app
MOC_DIR = moc
OBJECTS_DIR = obj
INCLUDEPATH = /usr/include/kde
QMAKE_LIBDIR_X11 += /usr/lib
QMAKE_LIBS_X11 += -lkdeui -lkdecore
SOURCES = main.cpp window.cpp
HEADERS = window.h
Вы задаете результирующий двоичный файл, временные каталоги moc и объектных файлов, путь к библиотеке KDE и исходные тексты, и заголовочные файлы, из которых формируется приложение. Учтите, что местонахождение файлов библиотек и заголовочных файлов KDE зависит от вашего дистрибутива. Пользователи SUSE должны приравнять INCLUDEPATH
путь /opt/kde3/include и QMAKE_LIBS_X11
путь /opt/kde3/lib.
$ qmake file.pro -о Makefile
Затем вы можете выполнить команду make
как обычно, что не вызовет затруднений. Для упрощения процедуры построения приложения следует использовать qmake
с программами любой сложности, применяющими KDE/Qt.
Создание меню и панелей инструментов с помощью KDE
Для того чтобы продемонстрировать мощь виджетов KDE, мы оставили меню и панели инструментов напоследок, поскольку они – уж очень наглядные примеры того, как библиотеки KDE экономят время и усилия по сравнению с применением только Qt или любых других комплектов с элементами графического пользовательского интерфейса.
Обычно в библиотеках GUI элементы меню и панелей инструментов – отличающиеся элементы, каждый со своим собственным виджетом. Вы должны создавать отдельные объекты для каждого элемента и отслеживать изменения, например, делая недоступными определенные варианты, каждый отдельно.
У программистов KDE появилось лучшее решение. Вместо такого обособленного подхода в KDE определен виджет KAction
для представления действия, которое может выполнить приложение. Это действие может открыть новый документ, сохранить файл или вывести окно справки.
KAction
присваивается текст, клавиатурный акселератор, пиктограмма и слот, который вызывается при активизации действия:
KAction *new_file = new KAction(«New», «filenew»,
KstdAccel::shortcut(KstdAccel::New), this,
SLOT(newFile()), this, «newaction»);
Затем KAction
может быть вставлено в меню и панель инструментов без дополнительного описания:
new_file->plug(a_menu);
new_file->plug(a_toolbar);
Таким образом, вы создали пункт меню New и кнопку панели инструментов, которые вызывают newFile
при щелчке кнопкой мыши.
Теперь если вам нужно отменить KAction
– скажем, вы не хотите, чтобы пользователь мог создать новый файл, – вызов централизован:
new_file->setEnabled(FALSE);
Это все, что касается меню и панелей инструментов в среде KDE – на самом деле очень легко и просто. Далее приведен конструктор виджета KAction
:
#include
KAction(const QString& text, const KShortcut& cut,
const QObject* receiver, const char* slot,
QObject *parent, const char* name = 0);
KDE предоставляет стандартные объекты KAction
для унификации текста, клавиатурных акселераторов и пиктограмм в разных приложениях KDE:
#include
KAction* openNew(const QObject* recvr, const char *slot,
KActionCollection* parent, const char* name = 0)ж
KAction* save ...
KAction* saveAs ...
KAction* revert ...
KAction* close ...
KAction* print ...
И т.д.
Любое стандартное действие принимает одни и те же параметры; слот-приемник и функцию, KActionCollection
и имя KAction
. Объект KActionCollection
управляет в окне объектами KAction
, и вы можете получить текущий объект с помощью метода actionCollection
окна KMainWindow
:
KAction *saveas = KStdAction::saveAs(this, SLOT(saveAs()) ,
actionCollection(), «saveas»);
Выполните упражнение 17.8.
Упражнение 17.8. Приложение в KDE с меню и панелями инструментов
В приведенном далее примере вы опробуете объекты KAction
в приложении среды KDE.
1. Начните с заголовочного файла KDEMenu.h. KDEMenu
– это подкласс KMainWindow
, являющегося подклассом класса QMainWindow
. KMainWindow
управляет сеансом в среде KDE и обладает встроенными панелью инструментов и строкой состояния.
#include
class KDEMenu : public KMainWindow {
Q_OBJECT
public:
KDEMenu(const char * name = 0);
private slots:
void newFile();
void aboutApp();
};
2. Файл KDEMenu.cpp начните с директив #include
для виджетов, которые будете применять:
#include «KDEMenu.h»
#include
#include
#include
#include
#include
3. В конструкторах, создающих три виджета KAction
, new_file
определяется вручную, a quit_action
и help_action
используют стандартные определения KAction
:
KDEMenu::KDEMenu(const char *name = 0) : KMainWindow (0L, name) {
KAction *new_file = new KAction(«New», «filenew»,
KstdAccel::shortcut(KstdAccel::New), this, SLOT(newFile()),
this, «newaction»);
KAction *quit_action = KStdAction::quit(KApplication::kApplication(),
SLOT(quit()), actionCollection());
KAction *help_action = KStdAction::aboutApp(this, SLOT(aboutApp()),
actionCollection());
4. Создайте два меню верхнего уровня и включите их в строку меню KApplication
:
QPopupMenu *file_menu = new QPopupMenu;
QPopupMenu *help_menu = new QPopupMenu;
menuBar()->insertItem(«&File», file_menu);
menuBar()->insertItem(«&Help», help_menu);
5. Теперь вставьте действия в меню и панель инструментов, добавив разделительную линию между new_file
и quit_action
:
new_file->plug(file_menu);
file_menu->insertSeparator();
quit_action->plug(file_menu);
help_action->plug(help_menu);
new_file->plug(toolBar());
quit_action->plug(toolBar());
}
6. В заключение несколько определений слотов: aboutApp
создает диалоговое окно KAbout
для отображения сведений о программе. Учтите, что слот quit
определен как часть KApplication
:
void KDEMenu::newFile() {
// Создание нового файла
}
void KDEMenu::aboutApp() {
KAboutDialog *about = new KAboutDialog(this, «dialog»);
about->setAuthor(QString(«A. N. Author»),
QString(«[email protected]»), QString(«http://url.com»),
QString(«work»));
about->setVersion(«1.0»);
about->show();
}
int main(int argc, char **argv) {
KApplication app(argc, argv, «cdapp»);
KDEMenu* window = new KDEMenu(«kdemenu»);
app.setMainWidget(window);
window->show();
return app.exec();
}
7. Далее вам нужен файл menu.pro для утилиты qmake
:
TARGET = kdemenu
MOC_DIR = moc
OBJECTS_DIR = obj
INCLUDEPATH = /usr/include/kde
QMAKE_LIBDIR_X11 += -L$KDEDIR/lib
QMAKE_LIBS_X11 += -lkdeui -lkdecore
SOURCES = KDEMenu.cpp
HEADERS = KDEMenu.h
8. Теперь запустите qmake
для создания make-файла, откомпилируйте и выполните программу:
$ qmake menu.pro -о Makefile
$ make
$ ./kdemenu
Как это работает
Несмотря на то, что этот пример получился чуть длиннее других, программный код довольно краток, если учесть всю выполняемую им работу по созданию строки меню и самих меню. Лучшее качество виджетов KAction
– возможность использования каждого из них в разных частях программы, таких как панель инструментов и меню в строке меню, все упомянутые возможности показаны в данном примере.
Построение приложений KDE требует больше работы, чем создание большинства программ, по крайней мере, на первый взгляд. В действительности файл menu.pro и команда qmake
скрывают большой набор параметров, которые в противном случае вам пришлось бы вставлять вручную в ваш make-файл.
На рис. 17.11 и 17.12 показано, как появляются в окне меню и кнопки панели инструментов.
Рис. 17.11
Рис. 17.12
И вот оно! Мы закончили наш тур по Qt и KDE, рассмотрев базовые элементы, всех приложений GUI, окна, схемы размещения, кнопки, диалоговые окна и меню. Существует бесчисленное множество виджетов Qt и KDE, о которых мы не упоминали, начиная с QColorDialog
– диалогового окна для выбора цвета – и заканчивая KHTML
– виджетом Web-обозревателя – все они подробно описаны на Web-сайтах компании Trolltech и графической среды KDE.