Язык программирования Python
Шрифт:
justify=CENTER, anchor=«se»)
c.create_oval((205, 205, 206, 206), outline=«red»)
c.pack
tk.mainloop
В результате работы этой программы на экране появится окно:
Следует заметить, что методы create_* создают объекты, свойства которых можно менять в дальнейшем: переместить в другое место, перекрасить, удалить, изменить порядок и т.д. В следующем примере можно нарисовать кружок, меняющий цвет по щелчку мыши:
Листинг
from Tkinter import *
from random import choice
colors = «Red Orange Yellow Green LightBlue Blue Violet».split
R = 10
tk = Tk
c = Canvas(tk, bg=«White», width=«4i», height=300, relief=SUNKEN)
c.pack(expand=1, fill=BOTH)
def change_ball(event):
c.coords(CURRENT, (event.x–R, event.y–R, event.x+R, event.y+R))
c.itemconfigure(CURRENT, fill=choice(colors))
oval = c.create_oval((100–R, 100–R, 100+R, 100+R), fill=«Black»)
c.tag_bind(oval, "<1>", change_ball)
tk.mainloop
Здесь нарисован кружок радиуса R , с ним связана функция change_ball по нажатию кнопки мыши. В указанной функции заданы новые координаты кружка (его центр расположен в месте щелчка мыши) и затем изменен цвет случайным образом методом itemconfigure. Тег CURRENT в Tkinter использован для указания объекта, который принял событие.
Графическое приложение на Tkinter
Теперь следует рассмотреть небольшое приложение, написанное с использованием Tkinter. В этом приложении будет загружен файл с графическим изображением. Приложение будет иметь простейшее меню File с пунктами Open и Exit, а также виджет Canvas, на котором и будут демонстрироваться изображения (опять потребуется пакет PIL):
Листинг
from Tkinter import *
import Image, ImageTk, tkFileDialog
global img, imgobj
def show:
global img, imgobj
# Запрос на имя файла
filename = tkFileDialog.askopenfilename
if filename != : # Если имя файла было задано пользователем
# рисуется изображение из файла
src_img = Image.open(filename)
img = ImageTk.PhotoImage(src_img)
# конфигурируется изображение на рисунке
c.itemconfigure(imgobj, image=img, anchor=«nw»)
tk = Tk
main_menu = Menu(tk) # формируется меню
tk.config(menu=main_menu) # меню добавляется к окну
file_menu = Menu(main_menu) # создается подменю
main_menu.add_cascade(label=«File», menu=file_menu)
# Заполняется меню File
file_menu.add_command(label=«Open», command=show)
file_menu.add_separator # черта для отделения пунктов меню
file_menu.add_command(label=«Exit», command=tk.destroy)
c = Canvas(tk, width=300, height=300, bg=«white»)
# готовим объект–изображение на рисунке
imgobj = c.create_image(0, 0)
c.pack
tk.mainloop
Приложение (с загруженной картинкой) будет выглядеть так:
Стоит отметить, что здесь пришлось применить две глобальные переменные. Это не очень хорошо. Существует другой подход, когда приложение создается на основе окна верхнего уровня. Таким образом, само приложение становится особым виджетом. Переделанная программа представлена ниже:
Листинг
from Tkinter import *
import Image, ImageTk, tkFileDialog
class App(Tk):
def __init__(self):
Tk.__init__(self)
main_menu = Menu(self)
self.config(menu=main_menu)
file_menu = Menu(main_menu)
main_menu.add_cascade(label=«File», menu=file_menu)
file_menu.add_command(label=«Open», command=self.show_img)
file_menu.add_separator
file_menu.add_command(label=«Exit», command=self.destroy)
self.c = Canvas(self, width=300, height=300, bg=«white»)
self.imgobj = self.c.create_image(0, 0)
self.c.pack
def show_img(self):
filename = tkFileDialog.askopenfilename
if filename != :
src_img = Image.open(filename)
self.img = ImageTk.PhotoImage(src_img)
self.c.itemconfigure(self.imgobj, image=self.img, anchor=«nw»)
app = App
app.mainloop
В объекте заключена информация, которая до этого была глобальной со всеми следующими из этого ограничениями. Можно пойти дальше и выделить в отдельный метод настройку меню (если приложение будет динамически изменять меню, объекты–меню тоже могут быть сохранены в приложении).
Примечание:
На некоторых системах новые версии Python плохо работают с национальными кодировками, в частности, с кодировками для кириллицы. Это связано с переходом на Unicode Tcl/Tk. Проблем можно избежать, если использовать кодировку UTF–8 в строках, которые должны выводиться в виджетах.
Заключение
В этой лекции было дано представление о (невизуальном) программировании графического интерфейса для Python на примере пакета Tkinter. Программа с графическим интерфейсом — событийно–управляемая программа, проводящая время в цикле обработки событий. События могут быть вызваны функционированием графического интерфейса или другими причинами (например, по таймеру). Обычно события возникают в виджетах и некоторые из них должны обрабатываться приложением. В Tkinter событие представлено отдельным объектом, из атрибутов которого можно установить, каково было положение указателя (курсора мыши), в каком виджете произошло событие и т.п.
Здесь были рассмотрены классы элементов интерфейса (виджеты), их свойства и методы. Виджеты имеют большое количество свойств и методов. Некоторые свойства и методы достаточно универсальны (их имеют все или почти все виджеты), другие же специфичны для конкретного класса виджетов. Графический пакет Python Imaging Library (PIL) предоставляет класс объекта для расположения в виджете–рисунке растрового графического изображения.
Виджеты располагаются внутри другого виджета (например, рамки) в соответствии с набором правил. Этот набор правил реализуют менеджеры расположения, которых в Tkinter три: pack, grid и place.