Создание GUI в Linux. Часть 1
В этой статье мы поговорим о создании графического интерфейса для вашей Linux-программы. Как вы знаете, средствами одного С нормальный GUI (Graphical User Interface – Графический интерфейс пользователя, ГИП) не построишь, тем более что после Windows пользователь очень требователен не только к наличию этого самого GUI, но еще и к дизайну формы (окна программы). Поэтому без дополнительных библиотек вам не обойтись. Самыми распространенными библиотеками для создания GUI являются библиотеки GTK и Qt. Рекомендуется использовать только эти библиотеки, поскольку велика вероятность того, что они уже будут установлены у пользователя (уж GNOME и KDE установлены почти у всех), чтобы не сложилась такая ситуация, когда размер вашей программы 300К, а используемая нею библиотека «весит» 20М. Вот подумайте, зачем пользователю ваша программа и станет ли он закачивать ее из сети? Конечно, если для вашего шедевра нет аналогов в мире, вы можете изрядно поиздеваться над пользователем, используя нестандартную библиотеку GUI. В первой части этой статьи будет рассмотрена библиотека GTK, а во второй – Qt. Сразу следует заметить, что эта статья – не русскоязычное руководство по библиотекам GTK и Qt. Это, скорее, небольшой обзор возможностей библиотек.
Скорее всего, GTK уже будет у вас установлена, но вам нужно будет установить пакет gtk+-devel, содержащий необходимые файлы для разработки GTK-программ.
Не хочется в этой статье рассматривать банальный пример окошка с кнопкой hello world!. Уж слишком уж это просто, да и этот пример вы сможете найти в документации по Gtk.
Сейчас напишем небольшой конфигуратор, который будет вносить изменения в файл /etc/resolv.conf. Напомню вам формат этого файла:
Директива domain определяет наш домен, а две директивы nameserver – первый и второй DNS-серверы, соответственно. Вместо директивы domain можно использовать директиву search, но это кому как нравится. Файл может содержать до 4 директив nameserver, но обычно указываются только два сервера DNS, поэтому мы не будем перегружать себя лишней работой. Но файл resolv.conf не главное в нашей статье – ведь мы разрабатываем GUI. Наш конфигуратор не будет вносить изменения в настоящий файл /etc/resolv.conf – для этого нужны права root, можно, конечно, вызвать auth для аутентификации, но мы не будем этого делать, чтобы не усложнять код программы.
Теперь небольшое вступление в GTK. Элементы ГИП – кнопки, поля ввода, переключатели и тому подобное называется виджитами. Если вы когда-нибудь работали в Delphi, виджиты подобны визуальным компонентам Delphi.
Как и в Delphi, основным элементом GUI является окно (форма в Delphi). Виджиты для размещения в окне помещаются в контейнер. В самом окне выравнивать виджиты можно с помощью вертикальных/горизонтальных боксов или же таблиц. Мне больше нравится второй способ, поэтому мы будем использовать именно таблицы.
Виджиты могут реагировать на сигналы, например, щелчок мышью. При этом вызывается функция-обработчик события (сигнала), если вы определили ее.
В качестве примера нарисуем кнопку и определим обработчик ее нажатия:
А вот функция hello():
Хватит теории, перейдем к практике. На рисунке 1 изображена уже готовая программа. Работает она так. Когда пользователь введет что-нибудь в поле ввода и нажмет Enter, программа отобразит введенный им текст на консоли. Когда пользователь нажмет Ок, введенная им информация будет еще раз выведена на консоль и записана в файл. При нажатии кнопки Quit программа завершит свою работу. Она должна также завершить работу при нажатии кнопки закрытия окна – в GTK программист сам определяет реакции на стандартные кнопки.
Вот текст программы. Внимательно читайте комментарии.
Я старался писать подробные комментарии, но все же кое-что осталось в тумане. Это координаты ячеек. Рассмотрим нашу таблицу 3х3:
Сначала указываются координаты по X, затем – по Y. Вот координаты кнопки Ok: 2,3,0,1. Это означает, что кнопка будет расположена в последнем столбике (2,3), но в первом ряду (0,1). Чтобы было понятнее: ОК по Х находится между 2 и 3, а по Y – между 0 и 1.
Теперь откомпилируем нашу программу:
Можно не использовать опцию -g, добавляющую отладочную информацию – размер файла станет меньше. Программа gtk-config сообщает компилятору всю необходимую информацию о библиотеке gtk. Обратите внимание на директиву #include <gtk/gtk.h>. Обычно файлы заголовков gtk находятся в другом каталоге, например, gtk-1.2, но это совсем не имеет значения – все необходимые параметры укажет программа gtk-config.
У вас некорректно отображаются русские названия надписей и кнопок? Эта проблема очень быстро устраняется с помощью GNOME Control Center – вам всего лишь нужно выбрать другой шрифт.
Форум русскоязычного сообщества Ubuntu
Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!
- Форум русскоязычного сообщества Ubuntu »
- Архив »
- Архив »
- Архив тем до 2016г »
- Делаем свой графический интерфейс для ubuntu
Автор Тема: Делаем свой графический интерфейс для ubuntu (Прочитано 4124 раз)
0 Пользователей и 1 Гость просматривают эту тему.
- Форум русскоязычного сообщества Ubuntu »
- Архив »
- Архив »
- Архив тем до 2016г »
- Делаем свой графический интерфейс для ubuntu
Страница сгенерирована за 0.042 секунд. Запросов: 23.
© 2012 Ubuntu-ru — Русскоязычное сообщество Ubuntu Linux.
© 2012 Canonical Ltd. Ubuntu и Canonical являются зарегистрированными торговыми знаками Canonical Ltd.
Сборка своего окружения
Здравствуйте, решил ознакомиться с линукс. Поставил debian, решил начать с внешнего вида, потому что планирую поставить эту систему на ноут и использовать на постоянной основе. Чуть позже я попробую другие дистрибутивы, но решил начать с дебиана, потому что слышал что он очень стабильный.
Гном мне не нравится, KDE слишком перегружено, мне хочется собрать своё окружение. Я удалил все окружения и сейчас у меня обычная консоль.
На сколько я понимаю, мне нужен оконный менеджер и панель, ну и для теста, какое-нибудь приложение, например файловый менеджер.
Мне нравится KWin, с панелью я ещё не определился, но наверное это будет xfce4-panel.
Проблема в том, что я не знаю как должен выглядеть процесс сборки. Я думал что мне нужно будет выполнить apt-get install kwin-common , поставится оконный менеджер и я смогу его как-то запустить и попаду в графический интерфейс, но прописав команду, оказалось что у меня уже установлен этот пакет, а я все ещё в консоли.
Подскажите пожалуйста, что мне следует сделать, что бы я получил рабочее окружение из запчастей которые нравятся мне, а не из готовых сборок. Перечислите минимальные составляющие окружения.
Создание приложений на GTK+ с использованием среды Glade
Данный пост посвящен созданию приложений с использованием кроссплатформенной библиотеки GTK+. Ориентирован он в основном на новичков? поэтому какие-то вещи возможно для многих покажутся очень простыми и банальными, но я постарался максимально подробнее всё описать, чтобы было понятно для всех.
Немалым достоинством этой библиотеки является то, что она бесплатна для коммерческого использования. В интернете не так много документации и действительно качественных статей по работе с GTK+. В очень многих примерах интерфейс программы пишется «ручками», что порой очень неудобно. Я сам с этим столкнулся и довольно часто больше времени тратил на то, чтобы правильно расположить виджеты (объекты) на форме, в контейнеры, а не сосредоточиться на решении поставленной задачи.
Я продемонстрирую как можно очень быстро создать интерфейс для GTK+ с помощью приложения для визуального создания графических интерфейсов Glade и интегрировать его в вашу программу. Glade не является ни компилятором, ни отладчиком. Он позволяет лишь описать интерфейс и представить его в файлах XML-формата GladeXML.
Базовым интерфейсом для библиотеки GTK+ является язык C. Но я в данном примере буду ипользовать C++. Соответственно появятся небольшие особенности, о которых я обязательно расскажу. Дистрибутив Linux я использую Ubuntu 10.04.
- Установка и запуск Glade3
- Создадим графический интерфейс нашего приложения в Glade3, расположив основные виджеты (объекты) в главном окне и контейнерах, определив события (Singnals, сигналы) для виджетов и их обработчик (Handler), т.е. процедуру в коде нашей программы, которая будет вызываться при наступлении данного сигнала
- напишем код программы: интегрируем XML файл с графическим интерфейсом, пропишем обработчики и немного функционала для демонстрации
- немного потестируем наше приложение
Установка и запуск Glade3
Предполагается, что у Вас уже установлен dev-пакет GTK+, если нет, то это можно сделать через консоль:
Установить Glade можно через Ubuntu Update Center или снова воспользовавшись консолью:
После установки запускаем через Applications — Programming — Glade Interface Designer
Устанавливаем все параметры как показано на рисунке. Версию инструментария (Toolkit Version) выбираем 2.16
Слева вы можете увидеть окно с набором различных виджетов. Те, кто работал с Windows Forms, или в среде разрабоки Delphi быстро разберутся. Справо два меню: одно показывает иерархию виджетов, а второе окно — окно свойств виджетов.
Создание графического интерфейса
Создание графического интерфейса для вашего GTK+ приложения начинается с задания главной формы — заглавного окна программы. Находим в левом меню в разделе TopLevels виджет Window.
Справа в окне Properties задаём свойства этого виджета:
Name: topWindow
Windows position: Centre
Default Width: 500
Default Height: 320
Переходим во вкладку Signals (сигнал, событие) и GtkObject ищем destroy, в столбце Handler (обработчик) пишем topWindow_destroy_cb или выбираем из списка. Это будет названием процедуры которая будет обрабатывать сигнал destroy — закрытие главной формы.
Далее мы планируем, чтобы в нашем приложении было главное меню, основная функциональная часть (это холст и меню выбора того. что нарисовать) и строка состояния. Берём виджет-контейнер Vertical Box в левом меню в разделе Containers и кладём его нашу главную форму. В появившемя диалоге выбираем Number of Items: 3. Это означает, что в создаваемый нами контейнер можно будет положить 3 виджета.
У нас в контейнере vbox1 есть 3, так называемых ячейки, или отсека. Во второй (по центру) отсек кладём Frame (раздел Containers меню виджетов). Смотрим справа на дерево виджетов. Внутри созданного виджета frame1 будут два виждета: alignment1 и label1 — их можно удалить. На этом пока немного отклонимся и обратимся к теории.
Понимание того, как в GTK+ происходит управление размером виджетов, является очень важными для создания правильных и эффективных графических интерфейсов. Этот процесс часто называют процессом согласования, состоящего из двух составляющих (2 этапа): запрашиваемый размер и выделяемый размер.
Этап запроса представляет собой некий рекурсивный вопрос: «Сколько места тебе нужно?». Главное окно задаёт его дочерним окнам, дочерние окна задают его своим дочерним окнам и так пока все виджеты, во всей этой иерархии не ответят.
- Дочерние виджеты ничего не знают о размерах виджетов-родителей
- Размер виджетов-родителей зависит от размеров дочерних виджетов
На втором этапе (выделение размера) происходит команда от родителя к дочернему виджету: «Здесь у тебя есть некоторое место, сделай всё, чтобы уместиться в него». Если у виджета более одного дочернего виджета, то задача этого этапа должным образом разделить свободное место между дочерними виджетами.
Теперь переходим к главной части нашего приложения. Идём в меню виджетов и выбираем Horizontal Panes в разделе Containers и кладём его на frame1. Нам нужно чтобы наша левая часть была фиксированного размера, правая нет. Снова идём в меню виджетов и ищем там Scrolled Window. И кладём сначала один, а потом и второй Scrolled Window в левый и правый отсек hpand1 (Horizontal Panes). У левого Scrolled Window, который называется scrolledwindow1, устанавливаем свойство (во вкладке Common)Width reguеst равным 145 — это и будет означать запрашиваемый размер (для процесса согласования). Так же следует проверить, чтобы во вкладке Packing свойство Resize у scrolledwindow1 было No, а у scrolledwindow2 Yes.
Из раздела Containers кладём сначала первый виджет ViewPort, а потом и второй на оба наших scrolledwindow1 и scrolledwindow2 соответственно.
Займёмся боковым нашим меню. Добавляем во ViewPort1 Vertical Box с 3 отсеками. И в каждый отсек добавляем Radio Button. У каждого Radio Button устанавливаем свойство Expand No, чтобы они не растягивались при увеличении размера родительского виджета. Также во вкладке Common можно задать Width и Height request тогда они будут размера такого какой мы укажем, а не по умолчанию. Но в любом случае изменяться в размере они будут. Изменим их свойства во вкладке General:
Name соответственно на rbutRectangle, rbutEllipse, rbutTriangle
Label соответственно на Прямоугольник, Эллипс, Треугольник
и для rbutEllipse и rbutTriangle укажем в свойстве Group rbutRectangle с помощью специального диалога.
Должно получиться вот так:
Теперь необходимо прописать события для каждого Radio Button. Во вкладке Signals без разницы либо для события GroupChanged, либо для toggled (я сделаю для него) пропишем обработчик rbutton_toggled_cb:
Теперь обратим к правой части нашего окна. Добавляем в ViewPort2 вертикальный контейнер Vertical Box с двумя отсеками. В верхний кладём обычный Label, а в нижний Drawing Area — это будет холст. У Label1 в свойстве label пишем Холст размером 300 x 200. Переходим во вкладку Packing и устанавливаем Expand в No.
Теперь наш холст.
Name: drawingarea
Expend: No
Width request: 300
Height request: 200
Event: ставим галочку Exposure
В Signals ищем expose-event и пишем или выбираем из списка:
drawingarea_expose_event_cb
Теперь нам нужно добавить строку состояния (в самый нижний отсек) и главное меню (в самый верхний отсек). В самый верхний кладём Menu Bar (раздел Containers меню виджетов), В самый нижний отсек Status Bar (раздел Control and Display меню виджетов), про его добавлении появиться диалог, выберете Number of Items: 1.
В menubar1 для нашего примера оставим только один пункт меню — выход из программы. Соответственно можно удалить: menuitem2, menuitem3, menuitem4. Потом раскрываем menuitem1, заходим в menu1 и удаляем так всё кроме imagemenuitem5. Это пункт Quit. Можно нажать на неё и посмотреть свойство во вкладке General окна свойств свойство Stock Item, в котором прописано gtk-quit. Там можно «поиграться». Можно вообще выбрать Custom label and image и самому всё задать. Это не так важно. Для imagemenuitem5 во вкладке Signals устанавливаем для сигнала activate (нажатие на пункт меню) точно такой же обработчик как и для закрытия формы: topWindow_destroy_cb.
Вот так должен выглядеть в итоге наш интерфейс. Сохраняем наш проект с именем mainForm. Файл будет называться mainForm.glade
Код нашей программы
Создадим файл Example1.cpp в той же папке куда сохранили mainForm.glade. Сначало я приведу целиком весь код, а потом объясню некоторые важные моменты.
Сначало мы объявляем те объекты. с которыми мы будем работать. Потом начинаем прописывать обработчики сигналов. Т.к. мы пишем на С++, пользуясь extern «C» объявляем topWindow_destroy_cb, drawingarea_expose_event_cb, rbutton_toggled_cb внешними функциями и указываем, что они должны связываться согласно порядку связывания в С. GtkBuilder содержит ссылки на все объекты из описания в Glade. Функция gtk_builder_get_object получает ссылку на объект с соответствующим именнем из GtkBuilder (в данном случае из builder). Функция gtk_builder_connect_signals служит для соединения функций-обработчиков в коде с прописанными соответственными обработчиками сигналов в нам GladeXML. Это происходит автоматически. Важно, чтобы имена в Glade и в коде совпадали. Приложение нормально скомпилируется, просто обрабатываться сигналы не будут, а если вы запустите через консоль программу, там будут отображены warning’s, что невозможно найти обработчик для такого-то сигнала.
Так же, т.к. мы пишем на С++ очень часто приходится пользоваться явным приведением типов. Например
если бы мы писали на C, то можно было бы обойтись и без явного привидения GTK_RADIO_BUTTON.
Для того, чтобы откомпилировать Вашу программу нужно использовать либо автоматическую систему сборки (например CMake), либо самому прописать makefile. Я на этом подробно останавливаться не буду. А лишь приведу пример описания makefile. В конце поста две самые последнии ссылки как раз касаются создания make file.
Компиляция происходит командой:
Небольшое тестирование нашей программы
… а затем изменяем размер окна
Как мы видим боковое меню и холст не растянулись и остались в тех же размерах, а вот контейнер, в котором холст, размеры изменил. И причём всё свободное пространство, которое появилось при увеличении размера формы досталось ему. Это всё потому что мы у scrolledwindow1 установили Width reguеst = 145 и resize Yes. Вот пример появления полос прокрутки как главное окно стало меньших размеров
А вот теперь я зайду в Glade3 и изменю у label1 свойство Expand в Yes. Проект не нужно перекомпилировать. Достаточно просто сохранить mainForm файл. И вот результат:
Почему так? Холст у нас фиксированного размера. А всё пространство, которое получается при увеличении главного окна, отдаётся виджету label1. Вы можете «поиграться» со всем этим делом. Например, установив обратно Expand в No и указав точное значение Height, например 70. И тогда снова будет фиксированный размер, но уже не по умолчанию, а тот, который зададите вы.
На этом этот пост оканчивается. Если эта тема будет интересна, у меня есть желание писать еще посты в этом направлении.