else:
txt.insert(END, frag) # фрагмент помещается в текст
# ссылки отмечаются подчеркиванием и синим цветом
txt.tag_config(«href», foreground=«Blue», underline=1)
# при щелчке мыши на тексте, отмеченном как «href»,
# следует вызывать fetch_url()
txt.tag_bind(«href», "<1>", fetch_url)
tk.mainloop() # запускается цикл событий
В результате (после нажатия на гиперссылку) можно увидеть примерно следующее:
Для придания некоторым участкам текста особых свойств необходимо их отметить тегом. В данном случае URL отмечается тегом href. Позднее с помощью метода tag_config() задаются свойства отображения текста, отмеченного таким тегом. Методом tag_bind() привязывается некоторое событие (щелчок мыши) с вызовом заданной функции (fetch_url()).
В самой функции fetch_url()нужно в начале определить, на какой именно участок текста пришелся щелчок мыши. Для этого с помощью метода tag_ranges() получаются все интервалы, которые отмечены как href. Для определения конкретного URL проводятся сравнения (методом compare()) точки щелчка мышью с каждым из интервалов. Так находится интервал, на который попал щелчок, и с помощью метода get()получается текстовое значение найденного интервала. Найдя URL, его в поле записываются адреса, и получается HTML–код, соответствующий URL.
Этот пример показывает основные принципы работы с форматированным текстом. Примененными методами арсенал виджета не исчерпывается. О других методах и свойствах можно узнать из документации.
Менеджеры расположения
Следующий пример достаточно нагляден, чтобы понять принципы работы менеджеров расположения, имеющихся в Tk. В трех рамках можно применить различные менеджеры: pack, grid и place:
Листинг
from Tkinter import *
tk = Tk()
# Создаем три рамки
frames = {}
b = {}
for fn in 1, 2, 3:
f = Frame(tk, width=100, height=200, bg=«White»)
f.pack(side=LEFT, fill=BOTH)
frames[fn] = f
for bn in 1, 2, 3, 4: # Создаются кнопки для каждой из рамок
b[fn, bn] = Button(frames[fn], text="%s.%s» % (fn, bn))
# Первая рамка:
# Сначала две кнопки прикрепляются к левому краю
b[1, 1].pack(side=LEFT, fill=BOTH, expand=1)
b[1, 2].pack(side=LEFT, fill=BOTH, expand=1)
# Еще две — к нижнему
b[1, 3].pack(side=BOTTOM, fill=Y)
b[1, 4].pack(side=BOTTOM, fill=BOTH)
# Вторая рамка:
# Две кнопки сверху
b[2, 1].grid(row=0, column=0, sticky=NW+SE)
b[2, 2].grid(row=0, column=1, sticky=NW+SE)
# и одна на две колонки в низу
b[2, 3].grid(row=1, column=0, columnspan=2, sticky=NW+SE)
# Третья рамка:
# Кнопки высотой и шириной в 40% рамки, якорь в левом верхнем углу.
# Координаты якоря 1/10 от ширины и высоты рамки
b[3, 1].place(relx=0.1, rely=0.1, relwidth=0.4, relheight=0.4, anchor=NW)
# Кнопка строго по центру. Якорь в центре кнопки
b[3, 2].place(relx=0.5, rely=0.5, relwidth=0.4, relheight=0.4, anchor=CENTER)
# Якорь по центру кнопки. Координаты якоря 9/10 от ширины и высоты рамки
b[3, 3].place(relx=0.9, rely=0.9, relwidth=0.4, relheight=0.4, anchor=CENTER)
tk.mainloop()
Результат следующий:
Менеджер pack просто заполняет внутреннее пространство на основании предпочтения того или иного края, необходимости заполнить все измерение. В некоторых случаях ему приходится менять размеры подчиненных виджетов. Этот менеджер стоит использовать только для достаточно простых схем расположения виджетов.
Менеджер grid помещает виджеты в клетки сетки (это очень похоже на способ верстки таблиц в HTML). Каждому располагаемому виджету даются координаты в одной из ячеек сетки (row — строка, column — столбец), а также, если нужно, столько последующих ячеек (в строках ниже или в столбцах правее) сколько он может занять (свойства rowspan или columnspan). Это самый гибкий из всех менеджеров.
Менеджер place позволяет располагать виджеты по произвольным координатам и с произвольными размерами подчиненных виджетов. Размеры и координаты могут быть заданы в долях от размера виджета–хозяина.
Непосредственно внутри одного виджета нельзя использовать более одного менеджера расположения: менеджеры могут наложить противоречащие ограничения на вложенные виджеты и внутренние виджеты просто не смогут быть расположены.
Изображения в Tkinter
Средствами Tkinter можно выводить не только текст, примитивные формы (с помощью виджета Canvas), но и растровые изображения. Следующий пример демонстрирует вывод иконки с растровым изображением (для этого примера нужно предварительно установить пакет Python Imaging Library, PIL):
Листинг
import Tkinter, Image, ImageTk
FILENAME = «lena.jpg» # файл с графическим изображением
tk = Tkinter.Tk()
c = Tkinter.Canvas(tk, width=128, height=128)
src_img = Image.open(FILENAME)
img = ImageTk.PhotoImage(src_img)
c.create_image(0, 0, image=img, anchor=«nw»)
c.pack()
Tkinter.Label(tk, text=FILENAME).pack()
tk.mainloop()
В результате получается:
Здесь использован виджет–рисунок (Canvas). С помощью функций из пакетов Image и ImageTk из PIL получается объект–изображение, подходящее для включения в рисунок Tkinter. Свойство anchor задает угол, который привязывается к координатам (0, 0) в рисунке. В данном примере это северо–западный угол (NW — North–West). Другие возможности: n (север), w (запад), s (юг), e (восток), ne, sw, se и с (центр).
В следующем примере показаны графические примитивы, которые можно использовать на рисунке (приведенные комментарии объясняют свойства графических объектов внутри виджета–рисунка):
Листинг
from Tkinter import *
tk = Tk()
# Рисунок 300x300 пикселей, фон — белый
c = Canvas(tk, width=300, height=300, bg=«white»)
c.create_arc((5, 5, 50, 50), style=PIESLICE) # Сектор («кусок пирога»)
c.create_arc((55, 5, 100, 50), style=ARC) # Дуга
c.create_arc((105, 5, 150, 50), style=CHORD, # Сегмент
start=0, extent=150, fill=«blue») # от 0 до 150 градусов
# Ломаная со стрелкой на конце
c.create_line([(5, 55), (55, 55), (30, 95)], arrow=LAST)
# Кривая (сглаженная ломаная)
c.create_line([(105, 55), (155, 55), (130, 95)], smooth=1)
# Многоугольник зеленого цвета
c.create_polygon([(205, 55), (255, 55), (230, 95)], fill=«green»)
# Овал
c.create_oval((5, 105, 50, 120), )
# Прямоугольник красного цвета с большой серой границей
c.create_rectangle((105, 105, 150, 130), fill=«red»,
outline=«grey», width=«5»)
# Текст
c.create_text((5, 205), text=" Hello», anchor=«nw»)
# Эта точка визуально обозначает угол привязки
c.create_oval((5, 205, 6, 206), outline=«red»)
# Текст с заданным выравниванием
c.create_text((105, 205), text=«Hello,\nmy friend!»,
justify=LEFT, anchor=«c»)
c.create_oval((105, 205, 106, 206), outline=«red»)
# Еще один вариант
c.create_text((205, 205), text=«Hello,\nmy friend!»,
justify=CENTER, anchor=«se»)
c.create_oval((205, 205, 206, 206), outline=«red»)
c.pack()
tk.mainloop()
В результате работы этой программы на экране появится окно:
Следует заметить, что методы create_* создают объекты, свойства которых можно менять в дальнейшем: переместить в другое место, перекрасить, удалить, изменить порядок и т.д. В следующем примере можно нарисовать кружок, меняющий цвет по щелчку мыши: