Поиск по блогу

четверг, 16 августа 2012 г.

Создание текстового просмотрщика (Встроенный)

Введение

Мы разберём один из важных, но не очень сложных примеров с официального сайта "Gnome", в котором показан пример создания Текстового просмотрщика, самого простейшего. Этот проект назовём "ГлупыйВаня" (SillyJohn)

Пример Кода

Сам код примера, после кода я объясню кратенько что, да как.

SillyJohn.vala

using Gtk;
public class SillyJohn : Window {

private TextView textView;

// Констурктор
public SillyJohn() {

// Заголово приложения
this.title = "Application to view text content";

// Размер по умолчанию
this.set_default_size(450, 450);

// Создаём объект "Панель инструментов"
var toolbar = new Toolbar();

// Указываем тип панели (Влияет на отображение)
toolbar.get_style_context().add_class(STYLE_CLASS_PRIMARY_TOOLBAR);

// Создаём кнопку на панели инструментов со свойствами из хранилища
var openButton = new ToolButton.from_stock(Stock.OPEN);
// Задаём параметр для кнопки, что кнопка важная и скрывать её нельзя
openButton.is_important = true;
// Добавляем кнопку на панель инструментов
toolbar.add(openButton);
// Присоединяем метод к событию "Щелчок"
openButton.clicked.connect(onOpenClicked);

// Создаём объект и помещаем его в поле класса
this.textView = new TextView();
// Устанавливаем запрет редактирования содержимого
this.textView.editable = false;
// Скрываем курсор
this.textView.cursor_visible = false;

// Создаём ячейку-прокрутку (необходимо для того чтобы если меняет размер ребёнка, появлялась полоса прокрутки)
var scroll = new ScrolledWindow(null, null);
// Задаём политику отображения полос прокрутки
scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
// Добавляем элемент отображения текста в ячейку-прокрутку
scroll.add(this.textView);

// создаём вертикальный контейнер
var vbox = new Box(Orientation.VERTICAL, 0);
// Начинаем укладывать элементы с начала (сверху)
// Укладываем Панель инструментов
vbox.pack_start(toolbar, false, true, 0);
// Укладываем ячейку-прокрутку
vbox.pack_start(scroll, true, true, 0);
// А теперь контейнер в котором лежит всё укладываем в окно
this.add(vbox);
}

// Метод который будет вызван в ответ на событие "Щелчок"
private void onOpenClicked() {
// Создаём объект выбора файла
// Задаём ему параметры (Заголвок, Кто родитель объекта, Действие выбора файла, Кнопка 1 со свойствами из хранилища, Ответ кнопки 1 при нажатии, Кнопка 2 со свойствами из хранилища, Ответ кнопки 2 при нажатии)
var fileChooser = new FileChooserDialog("Open a document", this, FileChooserAction.OPEN, Stock.CANCEL, ResponseType.CANCEL, Stock.OPEN, ResponseType.ACCEPT);
// Запускаем выбор файла, при нажатии кнопки сранить возвращённый результат
if (fileChooser.run() == ResponseType.ACCEPT) {
// Если была нажата кнопка открыть, передаём имя файла в метод
this.openFile(fileChooser.get_filename());
}
// Уничтожаем окно выбора файла
fileChooser.destroy();
}

// Метод открытия файла
private void openFile(string filename) {
// Ставим ловушку на ошибку, в случае неверного файла
try {
string text;
// Получаем содержимое файла и выводим его в переменную text
FileUtils.get_contents(filename, out text);
// Загружаем полученное содержимое из переменной text в буфер объект-отображателя
this.textView.buffer.text = text;
} catch (Error e) {
// В случае возникновения ошибки - вывести сообщение в консоль об ошибке
stderr.printf("Error: %s\n", e.message);
}
}

public static int main(string[] args) {
Gtk.init(ref args);

var window = new SillyJohn();
window.destroy.connect(Gtk.main_quit);
window.show_all();
Gtk.main ();
return 0;
}
}


Разбор полётов

TextView - Это класс библиотеки Gtk.

Window - Это класс от которого мы наследуем наш класс SillyJohn, который нужен для создания окна.

Toolbar - Это класс для панели инструментов.

toolbar.get_style_context().add_class(STYLE_CLASS_PRIMARY_TOOLBAR); - Данная строчка говорит что необходимо взять объект который представляет стилевой контекст панели управления и добавляет к нему стилевой класс "STYLE_CLASS_PRIMARY_TOOLBAR" (Скорее всего эта строчка будет работать только с GTK+-3.0, дело в том что начиная с версии 3, графическая среда GTK использует CSS, для построения интерфейсов. И скорее всего здесь мы добавляем к объекту класс, буд-то работаем с DHTML (DOM-структурой)).

ToolButton - Это класс для кнопки панели инструментов.

from_stock(Stock.OPEN) - Этот именованный конструктор позволяет создать кнопку с предустановленными параметрами (текстом и иконкой), данные берутся общесистемные.

is_important - Этот параметр позволяет задать важность кнопки. Важность кнопки, или элемента меню - от этого параметра зависит будет ли разрешено скрывать эллемент в случае непредвиденных ситуаций.

this.textView.editable = false; - задавая данный параметр как ложный, мы запрещаем изменять текст загруженный из файла в textView.

ScrolledWindow - Этот класс позволяет создавать область с полями прокрутки. Это необходимо если например предполагается расширение области, к примеру текстового пространства, и чтобы не менялся размер окна, будет появляться полосы прокрутки.

scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); - задаются параметры для прокрутки, 2 параметра автоматической прокрутки: для вертикальной и горизонтальной.

var vbox = new Box(Orientation.VERTICAL, 0); - В новых версиях GTK, имеется только один класс Коробок (Боксов), но он имеет параметры, быть ли ему вертикальным или горизонтальным, или решётчатым. Мы выбираем вертикальный

FileChooserDialog - Класс диалога выбора файлов

fileChooser.run() - Запускается окно, в данном месте произойдёт показ окна, и после того как пользователь нажмёт какую-нибудь кнопку, метод закончит выполнение и вернёт некоторый результат (В зависимости от кнопки, вернёт то что указывалось в конструкторе: ResponseType.CANCEL или ResponseType.ACCEPT)

this.openFile(fileChooser.get_filename()); - Передаём имя выбранного файла в метод openFile

fileChooser.destroy(); - уничтожается диалоговое-окно выбора файла (почему этим занимается не само окошко, а главное окно?!, это связанно с правилами ООП, следуя им, уничтожать объект должен тот же объект что его породил)

try - начало конструкции попытайся-поймай (try-catch), эта конструкция используется для вылавливания и выправления работы программы в местах где вероятнее всего может произойти ошибка, самый простой вариант - например если происходит деление на ноль, или пытаются открыть файл которого не существует, в этом случае конструкция try прекратит работу и тут же начнётся конструкция catch, в которой обычно выводится сообщение о том что произошла ошибка

FileUtils.get_contents(filename, out text); - Статический метод класса FileUtils (Который как вы могли догадаться занимается именно работой с файлами). В метод передаются 2 параметра, первый это имя файла, а второй передаётся с аннотацией (командой) "out". Данная команда скорее всего аналог использования в языке "C" указателей (&), это позволяет передать ссылку на память в области с которой нужно работать, следовательно позволяет вытащить результат из метода, без команды "return"

this.textView.buffer.text = text; - текст помещается в форму "textView" только через буфер, это связанно с особенностями структуры компонента.

stderr.printf("Error: %s\n", e.message); - вывод ошибки в консоль. Но вывод происходит не в потоке "stdout" - всё связанно с тем что для вывода ошибок имеется свой специальный поток "stderr", эта методика удобна, потому что сразу можно понять что является ошибкой критической, а что незначительным сообщением хода выполнения программы.

Умозаключения

Для компиляции программы нужно использовать пакет gtk+-3.0.
Компиляция: "valac --pkg gtk+-3.0 SillyJohn.vala"