Graphical User Interface

„ Програмиране с Python“, ФМИ

+--------------------------_OX
| - Стефан Кънев
| - Николай Бачийски
| - Точо Точев
| - Димитър Димитров
|....

01.05.2009

Какво искат идиотите?

План

curses

PyQt

pygtk

wxPython

tkinter

pygame

tkinter - Hello, word

from tkinter import *
import random

def wisdom():
  return random.choice([
    "Beautiful is better than ugly.",
    "Now is better than never.",
    "Simple is better than complex.",
    "Complex is better than complicated."])

root = Tk()

greeting = Label(root, text="Hello, world!")
greeting.pack(side=TOP)

def new_wisdom():
    greeting['text'] = wisdom()

be_wise = Button(root, text="Kind sir, may I have another?", command=new_wisdom)
be_wise.pack()

root.mainloop()

tkinter - Widget

Tk програмите се организират чрез дървовидна структура от компоненти. Тези компоненти се наричат Widget-и. Всеки Widget се конструира с родител и опции. Изключение правят само тези в основата на йерархията - инстанции на Tk и Toplevel. Те нямат нужда от родител.

from tkinter import *

root = Tk()

greeting = Label(root, text="I am a label")
greeting.pack()

root.mainloop()

tkinter - Опции

Всеки Widget има набор от опрции (options), които определят как изглежда. Те могат да се настройват с:

# widget = Widget(master, option1=value1, option2=value2)
widget.config(option1=value1, option2=value2)
widget['option1'] = value

Могат да се вземат с

print(widget['option1'])
print(widget.cget('option1'))

tkinter - Няколко основни widget-а

tkinter - Геометрии

Когато влагате компоненти един в друг, имате три алтернативи (наречени „геометрии“) за позициониране на децата.

tkinter - Пример за grid()

from tkinter import *

root = Tk()

x = Entry(root)
y = Entry(root)
result = Label(root, text="----")
logarithm = Button(root, text="log",)
exponent = Button(root, text="exp")

x.grid(row = 0, column = 0)
y.grid(row = 0, column = 1)
logarithm.grid(row = 1, column = 0)
exponent.grid(row = 1, column = 1)
result.grid(row = 2, column = 0, columnspan = 2)

root.mainloop()

tkinter - mathline.py v0.2

from tkinter import *
import math

root = Tk()
x, y = Entry(root), Entry(root)
result = Label(root, text="----")

def do_exp(): result['text'] = str(float(x.get()) ** float(y.get()))

def do_log(): result['text'] = str(math.log(float(y.get()), float(x.get())))

logarithm = Button(root, text="log", command=do_log)
exponent = Button(root, text="exp", command=do_exp)

x.grid(row = 0, column = 0)
y.grid(row = 0, column = 1)
logarithm.grid(row = 1, column = 0)
exponent.grid(row = 1, column = 1)
result.grid(row = 2, column = 0, columnspan = 2)

root.mainloop()

tkinter - Интерфейс за калкулатор

from tkinter import *

class Calculator(Frame):
    def _make_button(self, name, text, row, column, columnspan=1):
        button = Button(self, text=text)
        button.grid(row = row, column = column, 
        columnspan = columnspan, sticky=W+E)
        setattr(self, name, button)
    def __init__(self, master=None, **kwargs):
        Frame.__init__(self, master, **kwargs)
        number = Entry(self, text="", width = 20, justify='right')
        number.grid(row = 0, column = 0, columnspan = 3, stick=W+E)
        for n in range(0, 9): self._make_button('button_%s' % (n+1), str(n+1), n // 3 + 1, n % 3)
        self._make_button('result', '=', 0, 4); self._make_button('plus', '+', 1, 4)
        self._make_button('minus', '-', 2, 4);  self._make_button('multiply', '*', 3, 4)
        self._make_button('divide', '/', 4, 4); self._make_button('button_0', '0', 4, 0, 2)
        self._make_button('dot', '.', 4, 2)

root = Tk()
calc = Calculator(root)
calc.pack()
root.mainloop()

tkinter - Диалогови прозорци

Може да отваряте диалогови прозорци с messagebox.тиn(заглавие, съобщение, опции), като тип може да е:

from tkinter import messagebox
messagebox.showerror("Фал!", "Опа, стана фал!")

tkinter - Меню

Може да създавате менюта със Menu:

from tkinter import *

def show(text): print(text)

root = Tk()
menu = Menu(root)

file = Menu(menu)
file.add_command(label = "Open", command = lambda: show("Open!"))
file.add_command(label = "Save", command = lambda: show("Save!"))
file.add_separator()
file.add_command(label = "Close", command = lambda: show("Close!"))
menu.add_cascade(label = "File", menu = file)

about = Menu(menu)
about.add_command(label = "About", command = lambda: show("About!"))
menu.add_cascade(label = "Help", menu = about)

root.config(menu = menu)
root.mainloop()

tkinter - Събития

Може да прихващате събития с bind(event, handler), където event е текстов низ идентифициращ събитието, а handler е едноаргументна функция, която ще бъде извикана при настъпването на събитието.

from tkinter import *

def handle(event):
  print(event.x, event.y)

root = Tk()
frame = Frame(root, width=200, height=200)
frame.pack()
frame.bind("<Button-1>", handle)

root.mainloop()

tkinter - Canvas

Canvas е widget, който позволява да чертаете свобоно. Той предлага различни методи, чертаещи различни обекти:

tkinter - Canvas(2)

from tkinter import *

root = Tk()
canvas = Canvas(root, width=300, height=300)
canvas.pack()

canvas.create_line(0, 0, 300, 300, fill='red')
canvas.create_line(0, 300, 300, 0, fill='blue')

root.mainloop()

tkinter - items

Всеки начертан елемент в Canvas има уникален номер. Функциите create_* връщат този уникален номер. След това бихте могли да променяте опциите на начертания елемент чрез canvas.itemconfig(item, options) или да го триете чрез canvas.delete(item).

tkinter - Етикети

Може да маркирате обектите които чертаете със текстови низове, наречени етикети. Това става като подадете опция tags, която да съдържа низ (при единичен етикет) или n-орка от низове (при няколко етикета). После може да ги намирате с canvas.find_withtag(tag).

tkinter - tkinter.tix

модулът tkinter.tix ни дава по-богати Widget-и, примери:

Още въпроси?