-
Notifications
You must be signed in to change notification settings - Fork 119
Expand file tree
/
Copy pathtkui.py
More file actions
146 lines (102 loc) · 3.75 KB
/
tkui.py
File metadata and controls
146 lines (102 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""Modul s funkcemi pro okýnkové otázky a odpovědi:
input(otazka) -> str
nacti_cislo(otazka) -> int
ano_nebo_ne(otazka) -> bool
print(argument0, argument1, argument2, ..., argument_n, sep='')
"""
from tkinter import Tk, LEFT, RIGHT, BOTTOM, W
from tkinter.ttk import Label, Button, Spinbox, Entry
# Následující kód používá několik pokročilejších technik.
# Není důležité *jak* je kód napsaný, ale že je možné ho napsat – a že daná
# funkce má dané rozhraní :)
#
# Mimochodem; opravdové funkce input a print jsou ještě složitější; viz:
# https://github.com/python/cpython/blob/ce105541f/Python/bltinmodule.c#L1931
# https://github.com/python/cpython/blob/ce105541f/Python/bltinmodule.c#L1827
# Funkce používají modul tkinter, který je zabudovaný v Pythonu, ale okýnka
# s ním vytvořená nevypadají příliš profesionálně.
# Budeš-li chtít začít psát "okýnkové" programy, doporučuji začít rovnou
# s knihovnou jako Qt nebo GTK.
# Na Qt máme mimochodem lekci v pokročilém kurzu:
# viz https://naucse.python.cz/course/mi-pyt/intro/pyqt/
def input(otazka='odpověz'):
"""Zeptá se uživatele na otázku a vrátí odpověď jako řetězec."""
root = Tk()
root.title(otazka)
button = Button(root, text="OK", command=root.quit)
button.pack(side=RIGHT)
entry = Entry(root)
entry.pack(side=LEFT)
root.mainloop()
value = entry.get()
root.destroy()
return value
def nacti_cislo(otazka='Zadej číslo'):
"""Zeptá se uživatele na otázku a vrátí odpověď jako celé číslo."""
root = Tk()
root.title(otazka)
entry = Spinbox(root, from_=0, to=100)
entry.set('0')
entry.pack(side=LEFT)
# Předbíháme: vnořená funkce může přistupovat
# k proměnným "entry" a "root", které jsou
# lokální pro "vnější" funkci (nacti_cislo)
def ok_pressed():
text = entry.get()
try:
value = int(text)
except ValueError:
entry.set('sem zadej číslo!')
else:
root.quit()
button = Button(root, text="OK", command=ok_pressed)
button.pack(side=RIGHT)
root.mainloop()
value = int(entry.get())
root.destroy()
return value
def ano_nebo_ne(otazka='Ano nebo ne?'):
"""Dá uživateli na výběr Ano/Ne a vrátí odpověď True nebo False."""
root = Tk()
root.title(otazka)
value = False
# Předbíháme: "nonlocal" umožňuje *měnit*
# lokální proměnnou z vnější funkce.
def yes():
nonlocal value
value = True
root.quit()
def no():
nonlocal value
value = False
root.quit()
button = Button(root, text="Ano", command=yes)
button.pack(side=LEFT)
button = Button(root, text="Ne", command=no)
button.pack(side=RIGHT)
root.mainloop()
root.destroy()
return value
# Předbíháme: hvězdička v *args umožní že "print" bere proměnný
# počet argumentů; přes "args" se potom dá projít příkazem "for"
def print(*args, sep=' ', end='', file=None, flush=False):
"""Zobrazí dané argumenty."""
root = Tk()
root.title('print')
str_args = ''
for arg in args:
str_args = str_args + sep + str(arg)
button = Label(root, text=str_args[len(sep):] + end)
button.pack(anchor=W)
button = Button(root, text="OK", command=root.quit)
button.pack(side=BOTTOM)
root.bind('<Return>', (lambda e: root.quit()))
root.mainloop()
root.destroy()
# A tady je trik, jak kousek kódu nespustit když se modul importuje.
# Pro opravdové programy ale doporučuji spouštěcí modul, viz kurz.
if __name__ == '__main__':
print(input())
print(nacti_cislo())
print(ano_nebo_ne())
print('a', 'b', 'c', sep='; ', end='-')