Pull to refresh

GTK+ приложение на PHP

Reading time 4 min
Views 6.6K
image
Многим трудно поверить, но на PHP можно писать не только говнокод и скрипты, но и небольшие GUI приложения. Небольшие, потому что тема не очень популярна и слабо освещена в силу того, что существуют более удобные и мощные средства для разработки, соответсвенно инструментарий довольно сырой. Хотя для написания приложений «для себя» или же курсовых\дипломных вполне подойдет.
В статье приводится пример создания простого GTK+ приложения на PHP.

GTK+ — кроссплатформенная библиотека элементов интерфейса, популярная в Linux системах и последнее время довольно часто используется в Windows.

Попробую заранее ответить на вопрос: «Да зачем это нужно, можно же на Python написать?». Конечно же можно, но:
1. Трудно поверить, но есть люди которые хорошо знают PHP и у них нету времени западло учить Python, но нужно написать GUI app.
2. Написаное на PHP работает везде где есть PHP с необходимыми библиотеками(Windows, Linux, MaxOS).

Начнем


Обычно для демонстрации прелестей языка или библиотеки пишут HelloWorld!, но мы пойдем немного дальше и напишем калькулятор.

Весь процесс довольно прост и состоит из двух шагов:
1. Разработка интерфейса в Glade Interface Editor
2. Разработка приложения с использованием созданного на предыдущем шаге интерфейса.

Установка


Конечно же для создания интерфейса не обязательно использовать Interface Builder. Glade файл представляет собой xml, который можно написать руками или же создать интерфейс непостредственно в PHP скрипте. Но так как цель даной статьи показать простоту создания приложений, мы пойдем простым путем и воспользуемся Drag'n'Drop редактором интерфейсов.

Скачать можно тут: http://glade.gnome.org/sources.html
Или же:
[aptitude|yum] install glade

PHP библиотека которую мы будем использовать работает только с PHP 5.1 и выше, поэтому обзаводимся оным: http://php.net/downloads.php

По умолчанию GTK библиотеки нету в PHP, поэтому её нужно установить.
Качаем: http://gtk.php.net/download.php
Устанавливаем: http://gtk.php.net/manual/en/tutorials.installation.php
Для установки на Linux лучше тянуть исходники из SVN. Перед конфигурацией нужно утановить cairo-php:
pecl install cairo-beta

Если конфигурация падает ошибкой: "`lt_if_append_uniq(lt_decl_varnames,..." делаем в папке php-gtk:
cat /usr/share/aclocal/ltoptions.m4 /usr/share/aclocal/ltversion.m4 /usr/share/aclocal/ltsugar.m4 /usr/share/aclocal/lt~obsolete.m4 >> aclocal.m4

После чего перезапускаем ./buildconf и ./configure

Интерфейс


Никаких сложных фич придумывать не будем, сделаем простой интерфейс.

Сначала создаем Window из вкладки Common, которому ставим Visible=true. На окно перетягиваем Vertical Box с разделением на 3 региона. В верхний регион помещаем Menu Bar, в средний Text Entry, а в нижний Table(4x4) в которой создаем кнопки как на рисунке выше.
Теперь пропишем обработчики событий для элементов интерфейса.
Для каждой кнопки:
  1. Кликаем на кнопку
  2. Переходим на табу Signals
  3. В поле «Clicked» пишем enterValue для кнопок 0-9, performAction для кнопок операций и clearCalc для «С».
  4. Для того, чтобы в PHP можно было понять какая кнопка нажата, пропишем Name для каждой из них, например так:
    «0»: «input0»

    «9»: «input9»
    "*": «action_mul»
    "/": «action_div»
    "+": «action_add»
    "-": «action_min»
    "=": «action_calc»
    «C»: «action_clear»

И последний штрих — выход из приложения при клике на File->Quit, для этого ставим обработчик quit для сигнала activate для этого пункта меню.

После чего сохраняем созданную форму в файл calc.glade, в формате LibGlade, и помещаем в папку с будущим приложением.

Программирование

Создаем PHP файл «calc.php» в котором пишем:
<?php
$glade = new GladeXML('calc.glade');
Gtk::main();

Первая строка загружает файл с интерфейсом, вторая создает все элементы.

Запускаем и радуемся форме:
php calc.php

Теперь нужно написать реализацию обработчиков событий и собственно сам калькулятор.

Обработчики событий которые мы описали в Glade Interface Editor — обычные функции или методы PHP класса. В каждый обработчик при вызове передается один аргумент — объект для которого вызван обработчик. Для упрощения имя этого объекта будем использовать как идентификатор операции или значение которое нужно ввести.
Создадим класс «Calc» который будет содержать обработчики событий и методы необходимые для проведения исчислений:
<?php
class Calc {
	protected $glade;
	protected $firstParam = null;
	protected $operation = null;
	
	function __construct($glade) {
		$this->glade = $glade;
	}
	/* Посчитать результат операции */
	protected function calculate($operation) {
		$secondParam = (float) $this->glade->get_widget('entry1')->get_text();
		$firstParam = (float) $this->firstParam;
		$result = 0;
		switch($this->operation) {
			case '*': 
				$result = $firstParam * $secondParam; 
				break;
			case '/': 
				$result = ($secondParam > 0 ? $firstParam / $secondParam : 0); 
				break;
			case '+': 
				$result = $firstParam + $secondParam; 
				break;
			case '-': 
				$result = $firstParam - $secondParam; 
				break;
		}
		$this->glade->get_widget('entry1')->set_text($result);
		$this->firstParam = $result;
		$this->operation = null;
	}
	/* Выполнить операцию */
	public function performAction($obj) {
		if ($this->firstParam == null) {
			$this->firstParam = $this->glade->get_widget('entry1')->get_text();
			$this->glade->get_widget('entry1')->set_text('');
		} 
		if ($this->operation == null) {
			$this->operation = str_replace(
				array('action_mul', 'action_add', 'action_min', 'action_div'), 
				array('*', '+', '-', '/'), 
				$obj->name
			);
			$this->glade->get_widget('entry1')->set_text('');
		} else {
			$this->calculate($obj->name);
		}
	}
	/* Добавить символ к текущему значению поля ввода */
	public function enterValue($obj) {
		/* Так как у нас имена кнопок input0..input1, нужно вырезать "input" и получим значение */
		$this->glade->get_widget('entry1')->set_text(
			$this->glade->get_widget('entry1')->get_text().
			str_replace('input', '', $obj->name)
		);
	}
	/* Очистить поле ввода,а также значение первой переменной и выполняемую операцию */
	public function clearCalc($obj) {
		$this->firstParam = null;
		$this->operation = null;
		$this->glade->get_widget('entry1')->set_text('');
	}
	/* Выход */
	public function quit() {
		exit;
	}
}

И последнее, укажем, что все обработчики событий хранятся в классе Calc:
$glade->signal_autoconnect_instance(new Calc($glade));

Ну вот и все.
php calc.php

Весь код примера на Гитхабе: https://github.com/kooler/php-glade-example
Tags:
Hubs:
+32
Comments 51
Comments Comments 51

Articles