Как просто программировать в Linux. Разработка приложений с PyGTK

Как просто программировать в Linux. Разработка приложений с PyGTK

PyGTK — этот архив содержит модули, позволяющие использовать gtk в программах, написанных на Python'е. На текущий момент он представляет собой практически завершенный набор классов. Несмотря на низкий номер версии, код готов для использования и может применяться для написания комплексных программ умеренного уровня сложности.

В данной заметке мы напишем небольшой калькулятор используя pygtk. Мы детально рассмотрим каждый шаг создания программы, что позволит вам ближе познакомиться с пакетом.
Список необходимых пакетов:
• python — этот пакет входит в состав многих дистрибутивов. Неплохо, если вы умеете программировать на python'е. Но даже если вы не умеете программировать — не волнуйтесь! Просто следуйте инструкциям.
• pygtk — последние версии пакета вы найдете здесь:
ftp://ftp.daa.com.au/pub/james/python
ftp://ftp.gtk.org/pub/gtk/python/
ftp://ftp.python.org/pub/contrib/Graphics .

Теперь пора приступить к работе. Итак, во-первых, нам нужно создать окно. Окно, по своей сути, контейнер. Таблицы кнопок и прочие элементы располагаются в границах этого окна. Создайте новый файл stage1.py и с помощью текстового редактора добавьте следующие строки:
from gtk import *

win = GtkWindow()

def main():
win.set_usize(300, 350)
win.connect("destroy", mainquit)
win.set_title("Scientific Calculator")
win.show()
mainloop()

main()

Первая строка предназначена для импортирования методов из модуля gtk. Это означает, что теперь мы можем использовать его функции (классы, типы и пр.).
Затем мы создаем объект класса GtkWindow и называем его win. После этого настраиваем размер созданного окна. Первый аргумент — ширина, второй — высота.
Далее создается ассоциативная связь между сигналом delete (удалить окно) и функцией mainquit. Это встроенная функция gtk, которая будет вызываться в том случае, если текущее приложение может быть закрыто. Не стоит волноваться об этом. Просто примите к сведению, что каждый раз, когда мы закрываем окно (может быть, кликнув на кнопке с "крестиком" в его правом верхнем углу или как-то иначе), будет вызываться функция mainquit. Иными словами, закрывая окно, мы тем самым вынуждаем приложение-владельца прекращать свою работу.
Теперь настроим заголовок окна и вызовем метод show. Этот метод является неотъемлемой частью всех визуальных объектов. Мы всегда должны вызывать метод show после настройки параметров визуализации конкретного объекта. Только после этого изменения, внесенные в объект, становятся видны пользователю. Помните, что вы можете создать объект логически, но до тех пор, пока вы не вызовете его метод show, физически объект не будет виден.
mainloop тоже является встроенной функцией библиотеки gtk. Когда мы вызываем mainloop, то запущенное приложение ожидает в цикле события, которые должны произойти. В нашем случае окно появляется на экране и просто ждет. Ожидание наших действий происходит в теле функции mainloop. Только после того, как мы удалим окно, приложение покинет этот цикл.
Сохраните файл. Выйдите из редактора и, запустив терминал, введите команду:
python stage1.py

Скриншот примера:

Давайте приступим к созданию следующего файла, stage2.py, который будет описывать создание таблицы и кнопок. Запишите в него вот такой код:
from gtk import *

rows = 9
cols = 4

win = GtkWindow()
box = GtkVBox()
table = GtkTable(rows, cols, FALSE)
text = GtkText()
close = GtkButton("close")

button_strings = [ 'hypot(', 'e', ',', 'clear', 'log(', 'log10(', 'pow(',
'pi', 'sinh(', 'cosh(', 'tanh(', 'sqrt(',
'asin(', 'acos(', 'atan(', '(',
'sin(', 'cos(', 'tan(', ')',
'7', '8','9', '/', '4', '5', '6', '*', '1', '2', '3',
'-', '0', '.', '=', '+' ]

button = map(lambda i:GtkButton(button_strings[i]), range(rows*cols))

def main():
win.set_usize(300, 350)
win.connect("destroy", mainquit)
win.set_title("Scientific Calculator")

win.add(box)
box.show()

text.set_editable(FALSE)
text.set_usize(300,1)
text.show()
text.insert_defaults(" ")
box.pack_start(text)

table.set_row_spacings(5)
table.set_col_spacings(5)
table.set_border_width(0)

box.pack_start(table)
table.show()

for i in range(rows*cols):
y,x = divmod(i, cols)
table.attach(button[i], x,x+1, y,y+1)
button[i].show()

close.show()
box.pack_start(close)

win.show()
mainloop()

main()

Переменные rows и cols используются соответственно для хранения количества строк и столбцов с кнопками. Создаются четыре новых объекта: table, box, text и button (элементы table, box, text box и button соответственно). В качестве аргумента для инициализации объекта класса GtkButton используется надпись. И обратите внимание, что close — это кнопка с надписью "closed".
Массив button_strings используется для хранения надписей на кнопках. Символы и надписи, которые изображаются на вспомогательной клавиатуре калькулятора, хранятся именно здесь. Функция map создает 36 кнопок (rows*cols = 9*4). Надписи для них берутся из массива button_strings. Получается, что i-я кнопка содержит надпись, взятую из i-го элемента массива button_strings. Диапазон i — от 0 до 35 (rows*cols-1 = 9*4-1).
Теперь мы вставляем объект box в окно. В свою очередь, в него вставляется таблица, и уже в таблицу мы вставляем кнопки. Соответствующие методы show окна, таблицы и кнопок вызываются после того, как они логически созданы.

Используя метод set_editable объекта text с параметром FALSE (фактически, этот элемент представляет из себя строку ввода), настраиваем его для использования в режиме только для чтения. Это означает, что мы не сможем изменять его содержимое напрямую, при помощи клавиатуры или мышки. Метод set_usize настраивает размер объекта text, а insert_defaults задает пустую строку как значение, используемое по умолчанию. По окончании всех настроек он внедряется в объект box.
После этого в объект box вставляется таблица, в которой будут содержаться кнопки. Настройка атрибутов таблицы элементарна — в цикле вставляются девять строк по четыре кнопки в каждой. Для получения координат расположения каждой кнопки выполняем операцию целочисленного деления значения переменной i на cols — y,x = divmod(i, cols), сохраняя частное в переменной y, а остаток в x.
Последней вставляем кнопку close. Помните, что метод pack_start располагает вставляемый объект на первое свободное место в элементе box.
Сохраните файл и выполните команду python stage2.py

Результат наших трудов должен быть таким:

Для того, чтобы "оживить" калькулятор, было добавлено несколько новых функций. Их принято называть движком, или backend'ом. Строки, содержащие реализацию движка, добавлены в scical.py, и мы с вами подходим к заключительному этапу. Скрипт scical.py содержит все, что нужно для работы калькулятора:
from gtk import *
from math import *

toeval = ' '
rows = 9
cols = 4

win = GtkWindow()
box = GtkVBox()
table = GtkTable(rows, cols, FALSE)
text = GtkText()
close = GtkButton("close")

button_strings = [ 'hypot(', 'e', ',', 'clear', 'log(', 'log10(',
'pow(', 'pi',
'sinh(', 'cosh(', 'tanh(', 'sqrt(',
'asin(', 'acos(', 'atan(', '(',
'sin(', 'cos(', 'tan(', ')',
'7', '8', '9', '/', '4', '5', '6', '*',
'1', '2', '3', '-', '0', '.', '=', '+' ]

button = map(lambda i:GtkButton(button_strings[i]), range(rows*cols))

def myeval(*args):
global toeval
try:
b = str(eval(toeval))
except:
b = "error"
toeval = ''
else: toeval = b
text.backward_delete(text.get_point())
text.insert_defaults(b)

def mydel(*args):
global toeval
text.backward_delete(text.get_point())
toeval = ''

def calcclose(*args):
global toeval
myeval()
win.destroy()

def print_string(args,i):
global toeval
text.backward_delete(text.get_point())
text.backward_delete(len(toeval))
toeval = toeval + button_strings[i]
text.insert_defaults(toeval)

def main():
win.set_usize(300, 350)
win.connect("destroy", mainquit)
win.set_title("Scientific Calculator: scical (C) 2002 Krishnakumar.R, Share Under GPL.")

win.add(box)
box.show()

text.set_editable(FALSE)
text.set_usize(300,1)
text.show()
text.insert_defaults(" ")
box.pack_start(text)

table.set_row_spacings(5)
table.set_col_spacings(5)
table.set_border_width(0)
box.pack_start(table)
table.show()

for i in range(rows*cols):
if i==(rows*cols-2): button[i].connect("clicked",myeval)
elif (i==(cols-1)): button[i].connect("clicked",mydel)
else : button[i].connect("clicked",print_string,i)
y,x = divmod(i, 4)
table.attach(button[i], x,x+1, y,y+1)
button[i].show()

close.show()
close.connect("clicked",calcclose)
box.pack_start(close)

win.show()
mainloop()

main()

Добавлена новая переменная toeval. Она хранит строку, значение которой интерпретируется и которая хранит результаты этой операции. Ее значение отображается в объекте text в верхней части окна. Расчет производится после того, как нажата кнопка =. Это событие приводит к тому, что вызывается пользовательская функция myeval. Содержимое строки интерпретируется используя встроенную функцию python'а eval, и результат показывается в объекте text. Если вычисление произвести невозможно, то в качестве результата выводится строка error. Для этого используется механизм исключений (try...except).
Нажатие любой кнопки (используя мышку), за исключением кнопок с надписью closed, clear или =, приводит к тому, что вызывается функция print_string. Эта функция сперва очищает элемент text box, а затем добавляет к переменной toeval строку, которая связана с нажатой кнопкой и отображает новое значение toeval на экране.
Если мы нажмем кнопку close, то будет вызвана функция calcclose, которая уничтожит окно. Если же нажмем кнопку clear, то функция mydel очистит элемент text box. В основной функции (main) в цикле создания и добавления кнопок можно увидеть три новых выражения. Они нужны для того, чтобы настроить связи соответствующих кнопок с вызываемыми функциями. Таким образом к кнопке = присоединяется функция myeval, к кнопке clear функция mydel и т.д.
Вот и все: калькулятор готов к работе. Просто наберите в терминале "python scical.py", и вы получите работающую программу.
Скриншот финального релиза нашей программы:

По материалам Krishnakumar R.
Подготовил X-Stranger linux@hitech.by
http://www.linux.hitech.by



Компьютерная газета. Статья была опубликована в номере 42 за 2002 год в рубрике soft :: linux

©1997-2024 Компьютерная газета