воскресенье, 11 марта 2007 г.

Введение в Gtk#

Эта статья - введение для начинающих программировать на Gtk#. Она поможет тем, кто никогда ранее не программировал для GUI Gtk+. Программисты связанные с API GTK+ другими языками (в т.ч. C, C++, Perl, Python) так же найдут эту статью полезной, т.к. она объясняет основы процесса создания приложений на Mono/C#. Эта статья так же рассказывает об основах использования Glade и libglade как быстрого инструмента создания графического пользовательского интерфейса.

Что такое Gtk#?


Если говорить простым языком, Gtk# - это обертка над gtk+ - кроссплатформенным GUI фреймворком.

С сайта gtk+:
Gtk+ - это мультиплатформенный тулкит для создания графического пользовательского интерфейса. Предоставляя полный набор элементов, gtk+ пригоден для использования в различных проектах, как для небольши забав, так и для приложений уровня предприятия.

На сегодняшний день Gtk+ работает напрямую под любым X сервером, системой Direct Framebuffer и производными Microsoft Windows NT. Сама библиотека вышла из Linux, где она является основой для популярной рабочей среды GNOME. Gtk+ включен практически во все дистрибутивы Linux и прекрасно работает под управлением Windows NT.

Портирование библиотеки для использования напрямую в Mac OSX пока только в планах.

Одно из наиболее популярных заблуждений - то что для работы GTK# обязательно нужно использовать Mono. Это далеко от истины. GTK# может запускаться и работать на любой .NET совместимой среде. GTK# регулярно тестируется на MS.NET и Mono, но может быть запущена так же и на любой другой. Это означает что если вы пишите ваше приложения на GTK# и хотите чтобы ваше приложение было запущено под Windows, вы можете выбрать какую среду использовать - от Microsoft или Mono для Windows.

Установка


Первое что вы захотите сделать - это установить GTK# на ваш компьютер.

Для пользователей Linux, MacOSX, FreeBSD и др.: Проверьте наличие требуемых пакетов для разработки на GTK# в вашем дистрибутиве. Если не можете найти, попробуйте найти пакет который вам подойдет со страницы загрузки. Если и здесь вы не найдете пакета для своей платформы, вам нужно будет скомпилировать GTK# самостоятельно из исходников.

Для Windows: скачайте установочный пакет со страницы загрузок. Вполне возможно вы так же захотите скачать пакет интеграции GTK# для Visual Studio, который позволит использовать GTK# с Microsoft's Visual Studio без необходимости устанавливать Mono.

Внутри библиотек GTK#

GTK# состоит из следующих компонентов:

gtk-sharp Связи для тулкита gtk+ 2.x - кроссплатформенного тулкита для создания грфического пользовательского интерфейса
glib-sharp Связи для тулкита glib 2.x, который предоставляет низкоуровневое не-GUI ядро для gtk+
pango-sharp Связи к Pango - слой для работы и рендеринга с интернациональными текстами
atk-sharp связи к фреймворку atk
gdk-sharp низкоуровневый инструмент для отрисовки элементов gtk+
glade-sharp Glade# позволяет подгружать графические интерфейсы пользователя во время выполнения программы. Это наиболее простой путь создания Gtk# GUI.
art-sharp библиотека рендеринга и работы с векторной графикой
rsvg-sharp библиотека рендеринга SVG
gtk-dotnet интеграция пространства имен Gtk# с System.Drawing.
gnome-sharp Связи с GNOME
gnomevfs-sharp (*) связи для работы с файлами, MIME типами, иконками и т.п. в GNOME.
vte-sharp (*) связи к эмулятору VTE терминала.
gconf-sharp (*) Связи к системе хранения конфигурации GNOME
gtkhtml-sharp (*) Связи к легкому HTML виджету

* - Не доступны в патеке GTK# дляя Windows

Некоторые компоненты не включены в основную поставку GTK#, но заслуживают упоминания, т.к. имеют отношение к GTK# - это Gecko#, Gtksourceview#, Gsf#, Guile#, Gst# и dbus#.

Выбор между GTK# и Glade#


Когда люди начинают изучение Mono часто они могут растеряться - какую библиотеку использовать: Gtk# или Glade#. Для того чтобы понять что именно вам нужно вы должны понимать различия между тем что такое Glade# и что такое Gtk#. Gtk# - это ядро для использования окон и виджетов. Glade# наследуется от Gtk# и позволяет управлять ресурсами виджетов через XML файл. XML для описания вашего GUI может быть сгенерирован при помощи утилиты Glade - WYSIWYG GUI студии дизайна.

Для большинства окон Glade# - лучший выбор. Он экономит время за счет отсутствия необходимости написания программного кода для генерации пользовательского интерфейса и делает простым изменение интерфейса в будущем. Вся проблема именно в том что вам нужно. Glade# не может выполнять некоторые специфичные вещи (например, скрывать элементы, динамически подгружать новые части, изменять родителей виджетов и т.д.). Только опыт сможет вам подсказать что в данном конкретном случае выгоднее использовать.

Для быстрого ознакомления с Glade# вы можете захотеть взглянуть на этот скринкаст Ната Фридмана (Nat Friedman), в котором он создает простое графическое приложение всего за несколько минут.

Ваше первое приложение GTK#

Шаг 1: устройтесь поудобнее

Мы должны чувствовать себя комфортно. Откройте Dr. Pepper и включите любимую музыку. Хорошо, теперь мы готовы.

Шаг 2: создаем директорию и файлы

Для начала мыдолжны создать директорию для нашего маленького проекта. (Пользователи Windows: давайте не будем использовать пробелы в названии директории, чтобы избежать в дальнейшем головной боли).

Затем вы захотите открыть shell (Если вы в Windows, откройте меню Start и идите в "Programs->Mono 1.x.x->Mono Command Prompt". Это автоматически утсановит нужные пути, т.о. вам не нужно дополнительно ничего делать). Перейдите в только что созданную директорию. Мы будем часто использовать консоль, поэтому оставьте ее запущенной в фоне.

Вернемся к делу. Откройте свой любимый редактор (MonoDevelop, vi, emacs, notepad и т.д.) и создайте новый пустой проект (если это возможно) или создайте новый пустой файл. Сохраните файл под именем "helloworld.cs".

Шаг 3: Пишем код

Подразумевается что вы уже знакомы с C#, т.о. код описанный ниже не доолжен вызвать никаких проблем в понимании. Мы должны создать новый класс, использовать Gtk# и указать точку входа в нашу программу. Это будет выглядеть примерно так:

 using System;
using Gtk;

public class GtkHelloWorld {

public static void Main() {
Console.WriteLine("HelloWorld");
}

}

Это должно выглядеть очень знакомым для вас. Теперь мы воспользуемся компилятором для компиляции кода. Сохраним созданный файл и перейдем в консоль:

mcs -pkg:gtk-sharp-2.0 helloword.cs

для те кто пользовался csc компилятором в Windows параметр "-pkg:" может показаться малознакомым. Этого параметра не было в csc потому как Mono пришел к нам из мира Linux. Этото параметр позволяет указать на необходимость подключения пакета gtk-sharp-2.0. Т.е. система ищет файл "gtk-sharp-2.0.pc", который содержит данные о местоположении библиотеки для этого пакета (и множество другой информации). Т.е. мы не должны вводить что-то вроде "-r:gtk-sharp-2.0.dll -r:atk-sharp-2.0.dll -r:pango-sharp-2.0.dll ...." руками.

Шаг 4: Добавляем GUI

Давайте вернемся обратно к нашему коду. Уберем строчку с "Console.WriteLine". Первое что мы хотим сделать - создать новое окно:

 using System;
using Gtk;

public class GtkHelloWorld {

public static void Main() {
Application.Init();

//Create the Window
Window myWin = new Window("My first GTK# Application! ");
myWin.Resize(200,200);

//Create a label and put some text in it.
Label myLabel = new Label();
myLabel.Text = "Hello World!!!!";

//Add the label to the form
myWin.Add(myLabel);

//Show Everything
myWin.ShowAll();

Application.Run();
}
}

Теперь скомпилируем код как мы делали это ранее и запустим программу используя `mono HelloWorld.exe`. В итоге вы получите что-то вроде этого:

Мило, не правда ли?

Первая вещь, на которую я отел бы обратить ваше внимание, это то что в отличии от использования System.Windows.Forms мы не должны точно размещать нашу текстовую метку в окне. К примеру, мы не говорим 'myLabel.Left = 100' или 'myLabel.Width = 200' или что-то подобное для добавления текстовой метки. Мы просто указываем 'myWin.Add(...)'. Это связано с тем что 'Gtk.Window' это виджет, который наследуется от Bin, или виджета который размещен в контейнере.

Вторая вещь, которая могла вас заинтересовать, это использование выражений "Application.Init()" и "Application.Run()". Если вы когда-либо ранее использовали System.Windows.Forms это аналогично использованию "Application.Run()" во многих случаях. Обычно, когда приложения заканчивает обработку любого кода в основном потоке, приложение останавливается. Команда "ShowAll()" не блокирует код и продолжает дальнейшее выполнение кода (вплоть до остановки). Команда "Application.Init()" говорит оболочке выполнения "слушать" сигналы поступающие от Gtk.Windows и в момент когда выполняется "Application.Run()" выполнение кода передается основному циклу сообщений. Это позволяет оставаться приложению запущенным до тех пор пока не будут закрыты все окна. Для большей информации смотрите информацию об объекте Application.

Шаг 5: Заполняем окно

Сейчас скорее всего вы спрашиваете себя: "Как я смогу добавить новый виджет на окно, если оно может содержать только один виджет?". Окно действительно может содержать в себе только один виджет, но виджет сам по себе может содержать в себе множество других виджетов. Некоторые из виджетов наследуются от контейнера Gtk.Box, а в некоторых случаях и напрямую от контейнера. Контейнерный виджет Bin наследуется напрямую от виждета-контейнера, как и многие другие виджеты, но Bin может содержать в себе только один элемент управления.

Для того чтобы размещать любое количество виджетов в нашем окне, мы должны добавить на окно один из виджетов, который может содержать в себе другие виджеты. Существует огромное количество виджетов, которые могут делать это, но мы коснемся только некоторых из них, таких как HBox, VBox или Table.

Шаг 6: Добавляем события

Все классы которые наследуются от Widget предоставляют следующие события:
Многие из этих событий могут быть обработаны при помощи стандартного обработчика событий. К примеру:

public static void HandlerMethod(object obj, EventArgs args)

Пример обработки события нажатия на кнопку:

public static void ButtonPressHandler(object obj, ButtonPressEventArgs args)

ButtonPressEventArgs это класс наследуемый от EventArgs. Класс ButtonPressEventArgs, как и множество других в Gtk#, добавляет свойство Gtk.Event (или что-то наследуемое от Gtk.Event) к EventArgs.

Типы Gdk.Event:

К примеру, для использования события Gdk.Event мы можем использовать что-то вроде:

using Gdk;
...
widget.ButtonPressEvent += new ButtonPressEventHandler(ButtonPressHandler);
...
private void ButtonPressHandler(object obj, ButtonPressEventArgs args) {
// single click
if (args.Event.Type == EventType.ButtonPress) {
...
}
// double click
if (args.Event.Type == EventType.TwoButtonPress) {
...
}

// the left button was used
if (args.Event.Button == 1) {
...
}
}

В примере выше вы можете увидеть как мы можем обнаружить было ли одиночное нажатие мышкой или это был двойной клик.

Ваше первое Glade# приложение

Шаг 1: Что такое Glade#

Glade# это набор связей с libglade в C# для того чтобы легко создавать GUI приложения используя визуальные средства и сохранять их в формате, который приложение сможет использовать во время выполнения чтобы создать интерфейс. На данный момент существует две среды для генерирования файлов в формате glade: Glade и Stetic.

Что представляют из себя glade файлы ?

Файлы написанные на XML которые представляют собой интерфейс пользователя в Gtk+ со всеми аттрибутами и свойствами.

как выглядит файл .glade ?

файл gui.glade:
Файл .glade содержит в себе всю необходимую информацию для того чтобы библиотека libglade могла воссоздать нужный вам дизайн.

Шаг 2: Интеграция файлов Glade в нашу программу

Подразумевается что файл .glade уже был создан каким-либо путем, при помощи Glade или Stetic. Вы можете просмотреть видео об использовании Stetic.

Для использования в нашем примере мы предполагаем что glade файл был сохранен в файле под названием gui.glade, который содержит в себе определение окна window1, кнопки button1 и текстовой метки label1.

Мы должны создать директивы для использования Gtk# и Glade# а затем создать новый класс и точку входа в нашем приложении. Что-то вроде этого:

// file: glade.cs
using System;
using Gtk;
using Glade;
public class GladeApp
{
public static void Main (string[] args)
{
new GladeApp (args);
}

public GladeApp (string[] args)
{
Application.Init();

Glade.XML gxml = new Glade.XML (null, "gui.glade", "window1", null);
gxml.Autoconnect (this);
Application.Run();
}
}

Как компилировать?

Теперь мы должны откомпилировать наш исходный файл glade.cs используя пространство имен glade, которые находятся в glade-sharp DLL. Команда компиляции:

$ mcs -pkg:glade-sharp -resource:gui.glade glade.cs

При помощи этой команды мы создаем программу glade.exe, параметр -resource вставляет наш файл gui.glade в выполняемую программу.

Передавая null в качестве первого параметра в конструктор Glade.XML мы указываем libglade загружать glade файл из ресурсов. как вариант может быть использована загрузка из файла в файловой системе, что особенно полезно когда вы не хотите перекомпилировать приложение после каждого изменения файла интерфейса.

Если мы запустим нашу программу мы увидим наш GUI. В то же время нажатие на кнопку на даст нам никакого эффекта, т.к. мы не сопоставили никакого действия на событие виджета. Продолжайте чтение для того чтобы узнать как это можно сделать.

Шаг 3: Как использовать Glade# в моем коде

Для того чтбы получить доступ к виджету из gui.glade мы должны знать имя этого объекта и его тип. Использование виджета в C# происходит следующим образом (обратите так же внимание на аттрибуты [Widget]:

[Widget]
Тип Название;

Мы добавляем это определение в наш пример следующим образом:

using System;
using Gtk;
using Glade;
public class GladeApp
{
public static void Main (string[] args)
{
new GladeApp (args);
}

public GladeApp (string[] args)
{
Application.Init();

Glade.XML gxml = new Glade.XML (null, "gui.glade", "window1", null);
gxml.Autoconnect (this);
Application.Run();
}

[Widget]
Button button1;

[Widget]
Label label1;
}

Как добавлять события

Для добавления новых событий следуйте нижеуказанному примеру. Вы так же можете добавлять события через Glade.

using System;
using Gtk;
using Glade;
public class GladeApp
{
public static void Main (string[] args)
{
new GladeApp (args);
}

public GladeApp (string[] args)
{
Application.Init();

Glade.XML gxml = new Glade.XML (null, "gui.glade", "window1", null);
gxml.Autoconnect (this);

button1.Clicked += OnPressButtonEvent;

Application.Run();
}

[Glade.Widget]
Button button1;

[Glade.Widget]
Label label1;

public void OnPressButtonEvent( object o, EventArgs e)
{
Console.WriteLine("Button press");
label1.Text = "Mono";
}
}

Оригинал статьи: http://www.mono-project.com/GtkSharpBeginnersGuide

3 комментария:

Unknown комментирует...

Спасибо за отличный перевод. Очень интересный ресурс, буду заходить ;)

Unknown комментирует...
Этот комментарий был удален автором.
Анонимный комментирует...

Спасибо за новост