+: tkinter 133-138

This commit is contained in:
devfzn 2023-11-19 02:48:22 -03:00
parent 832abaf6b9
commit 0cccc5e48c
Signed by: devfzn
GPG Key ID: E070ECF4A754FDB1
21 changed files with 534 additions and 28 deletions

View File

@ -4,7 +4,7 @@ Guia interactiva con la resolución de los retos propuestos en el libro
[Python by Example](https://www.google.cl/books/edition/Python_by_Example/gDGdDwAAQBAJ)
de *Nichola Lacey*
## Retos básicos
### Retos Básicos
- [001-011](./basic/basic01.py)
- [012-019](./basic/basic02.py)
@ -14,7 +14,7 @@ de *Nichola Lacey*
- [045-051](./basic/basic06.py)
- [052-059](./basic/basic07.py)
## Retos Turtle
### Retos Turtle
- [060](./trtl/turtle01.py)
- [061](./trtl/turtle02.py)
@ -26,7 +26,7 @@ de *Nichola Lacey*
- [067](./trtl/turtle08.py)
- [068](./trtl/turtle09.py)
## Retos Intermedios
### Retos Intermedios
- [069-079](./interm/interm01.py)
- [080-087](./interm/interm02.py)
@ -36,6 +36,24 @@ de *Nichola Lacey*
- [111-117](./interm/interm06.py)
- [118-123](./interm/interm07.py)
### Retos Tkinter
- [124](./tkgui/tk01.py)
- [125](./tkgui/tk02.py)
- [126](./tkgui/tk03.py)
- [127](./tkgui/tk04.py)
- [128](./tkgui/tk05.py)
- [129](./tkgui/tk06.py)
- [130](./tkgui/tk07.py)
- [131](./tkgui/tk08.py)
- [132](./tkgui/tk09.py)
- [133](./tkgui/tk10.py)
- [134](./tkgui/tk11.py)
- [135](./tkgui/tk12.py)
- [136](./tkgui/tk13.py)
- [137](./tkgui/tk14.py)
- [138](./tkgui/tk15.py)
## Uso
```sh

19
main.py
View File

@ -13,7 +13,8 @@ def toc():
3) Intermedios 069-123
4) Tkinter 124-138
5) SQLite 139-145
...
6) Finales 146-150
s) Salir
"""
print(content)
@ -104,12 +105,12 @@ def tkinter_challenges():
clear()
print(content)
opcs_default(1)
selection = user_input(1)
selection = user_input(2)
match selection:
case 1:
tkgui.challenges01()
case 2:
#tkgui.challenges02()
tkgui.challenges02()
pass
case 'v':
return
@ -132,7 +133,7 @@ def main():
clear()
print(header)
toc()
selection = user_input(10)
selection = user_input(6)
match selection:
case 1:
basic_challenges()
@ -143,16 +144,10 @@ def main():
case 4:
tkinter_challenges()
case 5:
#sqlite_challenges()
pass
case 6:
pass
case 7:
pass
case 8:
pass
case 9:
pass
case 10:
#final_challenges()
pass
case 's':
select_ok = True

57
tkgui/example02.py Normal file
View File

@ -0,0 +1,57 @@
import tkinter as tk
window = tk.Tk()
window.geometry("606x606")
window.configure(background="cyan")
title_icon = tk.PhotoImage(file = "./imgs/devfzn_64x64.png")
window.iconphoto(False, title_icon)
#logo = tk.PhotoImage(file = "./imgs/devfzn_250x250.png")
#logoimage = tk.Label(image=logo)
#logoimage.place(x=3, y=3, width=600, height=600)
# Re-asignable
photo1 = tk.PhotoImage(file = "./imgs/devfzn_250x250.png")
photobox1 = tk.Label(window, image=photo1)
photobox1["image"] = photo1
photobox1.place(x=3,y=3,width=600,height=600)
sel_name = tk.StringVar(window)
sel_name.set("Selecciona nombre")
lst_name = tk.OptionMenu(window, sel_name, "Bob", "Ret", "Znorb")
lst_name.place(x=253, y=75)
photo2 = tk.PhotoImage(file = "./imgs/img_4.png")
photobox2 = tk.Label(window, image=photo2)
photobox2.place(x=203,y=203,width=250,height=250)
lbl_msg = tk.Message(text='', font="Verdana 48")
lbl_msg.place(x=80, y=520, width=420, height=60)
lbl_msg["justify"] = "center"
def clicked():
sel = sel_name.get()
msg = f"Hola {sel}"
lbl_msg["text"] = msg
match sel:
case 'Bob':
photo = tk.PhotoImage(file = "./imgs/img_1.png")
photobox2.image = photo
case 'Ret':
photo = tk.PhotoImage(file = "./imgs/img_2.png")
photobox2.image = photo
case 'Znorb':
photo = tk.PhotoImage(file = "./imgs/img_3.png")
photobox2.image = photo
case _:
photo = tk.PhotoImage(file = "./imgs/devfzn_250x250.png")
photobox2.image = photo
photobox2["image"] = photo
photobox2.update()
button = tk.Button(text="Click", command=clicked)
button.place(x=253, y=30, width=150, height=25)
window.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
tkgui/imgs/devfzn_64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
tkgui/imgs/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
tkgui/imgs/iconart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
tkgui/imgs/img_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
tkgui/imgs/img_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
tkgui/imgs/img_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
tkgui/imgs/img_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
tkgui/imgs/ini.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
tkgui/imgs/ok.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

53
tkgui/tk10.py Normal file
View File

@ -0,0 +1,53 @@
from os import getcwd as pwd
import tkinter as tk
def tk_10():
"""Create your own icon that consists of several vertical multi-coloured
lines. Create a logo which measures 200 x 150, using Paint or another
graphics package. Create the following window using your own icon and
logo.When the user enters their name and clicks on the Press Me button
it should display "Hello" and their name in the second text box."""
base_path = f"{pwd()}/tkgui/imgs"
c_bg="magenta"
window = tk.Tk()
window.geometry("400x300")
window.configure(background=c_bg)
title_icon = tk.PhotoImage(file = f"{base_path}/devfzn_64x64.png")
window.iconphoto(False, title_icon)
window.title("Saludo Tk")
photo1 = tk.PhotoImage(file = f"{base_path}/img_4.png")
photobox1 = tk.Label(window, image=photo1)
photobox1["image"] = photo1
photobox1["bg"] = c_bg
photobox1.place(x=70,y=0,width=250,height=200)
name_in = tk.Entry()
name_in.place(x=120, y=200, width=160, height=30)
lbl_name = tk.Message(text="Nombre", font="Verdana 12")
lbl_name["bg"] = c_bg
lbl_name["width"] = 70
lbl_name["justify"] = "center"
lbl_name.place(x=40, y=200, width=70, height=30)
lbl_msg = tk.Message(text="", font="Verdana 18")
lbl_msg.place(x=160, y=240, width=200, height=30)
lbl_msg["justify"] = "left"
lbl_msg["width"] = 200
lbl_msg["bg"] = c_bg
def clicked():
sel = name_in.get()
name_in["text"] = ""
msg = f"Hola {sel}"
lbl_msg["text"] = msg
name_in.focus()
button = tk.Button(text="Click", command=clicked)
button.place(x=40, y=240, width=100, height=30)
name_in.focus()
window.mainloop()

97
tkgui/tk11.py Normal file
View File

@ -0,0 +1,97 @@
from os import getcwd as pwd
import tkinter as tk
from random import randint
def tk_11():
"""Create a new program that will generate two random whole numbers between
10 and 50. It should ask the user to add the numbers together and type in
the answer. If they get the question correct, display a suitable image such
as a tick; if they get the answer wrong, display another suitable image such
as a cross. They should click on a Next button to get another question."""
base_path = f"{pwd()}/tkgui/imgs"
window = tk.Tk()
window.title("Sumas TK")
window.geometry("380x470")
title_icon = tk.PhotoImage(file = f"{base_path}/devfzn_64x64.png")
window.iconphoto(False, title_icon)
def generate():
num = randint(10,50)
txt_box_1["fg"] = "black"
txt_box_1["bg"] = "magenta"
txt_box_1["text"] = f"{num}"
num = randint(10,50)
txt_box_2["fg"] = "black"
txt_box_2["bg"] = "magenta"
txt_box_2["text"] = f"{num}"
txt_num_in.delete(0, 'end')
img_ini = tk.PhotoImage(file = f"{base_path}/ini.png")
box_img.image = img_ini
box_img["image"] = img_ini
box_img.update()
lbl_resp["text"] = ""
txt_num_in.focus()
lbl_info = tk.Label(text="SUMA", font="Verdana 50")
lbl_info.place(x=40, y=25, width=300, height=75)
txt_box_1 = tk.Message(text="", font="Verdana 30")
txt_box_1["fg"] = "red"
txt_box_1["bg"] = "cyan"
txt_box_1["justify"] = "center"
txt_box_1["width"] = 80
txt_box_1.place(x=40, y=160, width=80, height=80)
lbl_plus = tk.Label(text="+", font="Verdana 20")
lbl_plus.place(x=125, y=185, width=20, height=20)
lbl_equal = tk.Label(text="=", font="Verdana 20")
lbl_equal.place(x=235, y=185, width=20, height=20)
txt_box_2 = tk.Message(text="", font="Verdana 30")
txt_box_2["fg"] = "red"
txt_box_2["bg"] = "cyan"
txt_box_2["justify"] = "center"
txt_box_2["width"] = 80
txt_box_2.place(x=150, y=160, width=80, height=80)
def check():
num_1 = txt_box_1["text"]
num_2 = txt_box_2["text"]
resp = txt_num_in.get()
resp = resp.replace(' ', '')
if resp.isdigit() and (int(resp) == int(num_1)+int(num_2)):
lbl_resp["text"] = "¡Correcto!"
img_resp = tk.PhotoImage(file = f"{base_path}/ok.png")
box_img.image = img_resp
else:
lbl_resp["text"] = "¡Incorrecto!"
img_resp = tk.PhotoImage(file = f"{base_path}/error.png")
box_img.image = img_resp
box_img["image"] = img_resp
box_img.update()
btn_launch.focus()
btn_launch = tk.Button(text="Generar", command=generate)
btn_launch.place(x=40, y=110, width=300, height=35)
btn_launch.focus()
txt_num_in = tk.Entry(font="Verdana 30")
txt_num_in["fg"] = "black"
txt_num_in["bg"] = "cyan"
txt_num_in["justify"] = "center"
txt_num_in["width"] = 4
txt_num_in.place(x=265, y=160, width=80, height=80)
btn_check = tk.Button(text="Comprobar", command=check)
btn_check.place(x=40, y=260, width=300, height=35)
lbl_resp = tk.Label(text="", font="Verdana 20")
lbl_resp.place(x=40, y=400, width=300, height=75)
img_ini = tk.PhotoImage(file = f"{base_path}/ini.png")
box_img = tk.Label(window, image=img_ini)
box_img["image"] = img_ini
box_img.place(x=138,y=310,width=100,height=100)
window.mainloop()

57
tkgui/tk12.py Normal file
View File

@ -0,0 +1,57 @@
from os import getcwd as pwd
import tkinter as tk
def tk_12():
"""Create a simple program that shows a drop-down list containing several
colours and a Click Me button. When the user selects a colour from the list
and clicks the button it should change the background of the window to that
colour. For an extra challenge, try to avoid using an if statement to do this."""
base_path = f"{pwd()}/tkgui/imgs"
window = tk.Tk()
window.title("Colores TK")
window.geometry("380x400")
title_icon = tk.PhotoImage(file = f"{base_path}/devfzn_64x64.png")
window.iconphoto(False, title_icon)
window["bg"] = "white"
colours = [
'dark slate gray',
'slate gray',
'cornflower blue',
'dodger blue',
'deep sky blue',
'dark turquoise',
'pale goldenrod',
'tomato',
'violet red',
'purple',
'DarkOrchid2',
'DarkOrchid4',
]
lbl_info = tk.Label(text="COLORES", font="Verdana 50")
lbl_info["bg"] = "white"
lbl_info.place(x=40, y=25, width=300, height=75)
lst_color = tk.Listbox()
for i, color in enumerate(colours):
lst_color.insert(i, color)
lst_color["justify"] = "center"
lst_color.place(x=40, y=160, width=300, height=220)
def apply_color():
try:
color = lst_color.curselection()[0]
window["bg"] = colours[color]
lbl_info["bg"] = colours[color]
except IndexError:
window["bg"] = "white"
lbl_info["bg"] = "white"
lst_color.focus()
btn_chng_color = tk.Button(text="Aplicar Color", command=apply_color)
btn_chng_color.place(x=40, y=110, width=300, height=35)
btn_chng_color.focus()
window.mainloop()

60
tkgui/tk13.py Normal file
View File

@ -0,0 +1,60 @@
from os import getcwd as pwd
import tkinter as tk
def tk_13():
"""Create a program that will ask the user to enter a name and then select
the gender for that person from a drop-down list. It should then add the
name and the gender (separated by a comma) to a list box when the user
clicks on a button."""
base_path = f"{pwd()}/tkgui/imgs"
window = tk.Tk()
window.title("Personal Data TK")
window.geometry("590x200")
title_icon = tk.PhotoImage(file = f"{base_path}/devfzn_64x64.png")
window.iconphoto(False, title_icon)
common_bg = "dodger blue"
window["bg"] = common_bg
gender_ops = [ 'Privado', 'Masculino', 'Femenino', 'Otro' ]
lbl_info = tk.Label(text="Lista Usuarios", font="Verdana 18")
lbl_info["bg"] = common_bg
lbl_info.place(x=20, y=20, width=200, height=20)
box_name = tk.Entry()
box_name["justify"] = "left"
box_name.place(x=120, y=62, width=140, height=30)
box_name.focus()
sel_gen = tk.StringVar(window)
sel_gen.set("género")
lst_genders = tk.OptionMenu(window, sel_gen, *gender_ops)
lst_genders.place(x=275, y=60, width=100)
lst_users = tk.Listbox()
lst_users["justify"] = "center"
lst_users.place(x=400, y=50, width=150, height=100)
def add_user():
name = box_name.get()
gender = sel_gen.get()
if gender != "género" and name != '':
new_user = f"{name},{gender}"
lst_users.insert('end', new_user)
box_name.delete(0,'end')
sel_gen.set("género")
box_name.focus()
else:
lst_genders.focus()
btn_add = tk.Button(text="Agregar usuario", command=add_user)
btn_add.place(x=40, y=110, width=340, height=35)
lbl_name = tk.Message(text="NOMBRE", font="Verdana 12")
lbl_name["bg"] = common_bg
lbl_name["width"] = 70
lbl_name["justify"] = "left"
lbl_name.place(x=40, y=62, width=70, height=25)
window.mainloop()

75
tkgui/tk14.py Normal file
View File

@ -0,0 +1,75 @@
from os import getcwd as pwd
import tkinter as tk
def tk_14():
"""Change program 136 so that when a new name and gender is added to the
list box it is also written to a text file. Add another button that will
display the entire text file in the main Python shell window."""
base_path = f"{pwd()}/tkgui/imgs"
file_path = f"{pwd()}/tkgui/files/users.txt"
window = tk.Tk()
window.title("Personal Data TK")
window.geometry("590x220")
title_icon = tk.PhotoImage(file = f"{base_path}/devfzn_64x64.png")
window.iconphoto(False, title_icon)
common_bg = "dodger blue"
window["bg"] = common_bg
gender_ops = [ 'Privado', 'Masculino', 'Femenino', 'Otro' ]
lbl_info = tk.Label(text="Lista Usuarios", font="Verdana 18")
lbl_info["bg"] = common_bg
lbl_info.place(x=20, y=20, width=200, height=20)
box_name = tk.Entry()
box_name["justify"] = "left"
box_name.place(x=120, y=62, width=140, height=30)
box_name.focus()
sel_gen = tk.StringVar(window)
sel_gen.set("género")
lst_genders = tk.OptionMenu(window, sel_gen, *gender_ops)
lst_genders.place(x=275, y=60, width=100)
lst_users = tk.Listbox()
lst_users["justify"] = "center"
lst_users.place(x=400, y=50, width=150, height=140)
def add_user():
name = box_name.get()
gender = sel_gen.get()
if gender != "género" and name != '':
new_user = f"{name},{gender}"
lst_users.insert('end', new_user)
box_name.delete(0,'end')
sel_gen.set("género")
box_name.focus()
with open(file_path, '+a') as file:
file.write(new_user+"\n")
else:
lst_genders.focus()
def show_users():
print(("NOMBRE".rjust(10)).ljust(15), "GENERO".rjust(10))
with open(file_path, 'r') as file:
users = file.readlines()
for user in users:
name = user.split(',')[0]
gender = user.split(',')[1].replace('\n','')
print((name.rjust(10)).ljust(15),
(gender.ljust(10)).rjust(12))
btn_add = tk.Button(text="Agregar usuario", command=add_user)
btn_add.place(x=40, y=110, width=340, height=35)
lbl_name = tk.Message(text="NOMBRE", font="Verdana 12")
lbl_name["bg"] = common_bg
lbl_name["width"] = 70
lbl_name["justify"] = "left"
lbl_name.place(x=40, y=62, width=70, height=25)
btn_show = tk.Button(text="Mostrar en Consola", command=show_users)
btn_show.place(x=40, y=150, width=340, height=35)
window.mainloop()

53
tkgui/tk15.py Normal file
View File

@ -0,0 +1,53 @@
from os import getcwd as pwd
import tkinter as tk
def tk_15():
"""Save several images in the same folder as your program and call them
1.gif, 2.gif, 3.gif, etc. Make sure they are all .gif files. Display one
in a window and ask the user to enter a number. It should then use that
number to choose the correct file name and display the correct image."""
path_base = f"{pwd()}/tkgui/imgs"
com_bg = "DarkOrchid2"
window = tk.Tk()
window.geometry("310x420")
window.configure(background=com_bg)
title_icon = tk.PhotoImage(file = f"{path_base}/devfzn_64x64.png")
window.iconphoto(False, title_icon)
photo1 = tk.PhotoImage(file = f"{path_base}/devfzn_250x250.png")
lbl_img = tk.Label(window, image=photo1)
lbl_img["image"] = photo1
lbl_img["bg"] = com_bg
lbl_img.place(x=30,y=160,width=250,height=250)
ent_num = tk.Entry(font="Verdana 20")
ent_num["justify"] = "center"
ent_num.place(x=200, y=100, width=50, height=50)
lbl_msg = tk.Message(text="Ingresa un número (1-4)", font="Verdana 16")
lbl_msg["width"] = 150
lbl_msg["bg"] = com_bg
lbl_msg["justify"] = "center"
lbl_msg.place(x=40, y=95, width=150, height=60)
def clicked():
sel = ent_num.get()
sel = sel.replace(' ', '')
if sel.isdigit() and (0 < int(sel) < 5):
photo = tk.PhotoImage(file = f"{path_base}/img_{sel}.png")
lbl_img.image = photo
else:
ent_num.delete(0, 'end')
photo = tk.PhotoImage(file = f"{path_base}/error.png")
lbl_img.image = photo
lbl_img["image"] = photo
lbl_img.update()
ent_num.focus()
button = tk.Button(text="Click", command=clicked)
button["bg"] = "tomato"
button.place(x=40, y=30, width=220, height=50)
ent_num.focus()
window.mainloop()

View File

@ -1,12 +1,20 @@
from . import tk01 as ex01
from . import tk02 as ex02
from . import tk03 as ex03
from . import tk04 as ex04
from . import tk05 as ex05
from . import tk06 as ex06
from . import tk07 as ex07
from . import tk08 as ex08
from . import tk09 as ex09
from . import (
tk01 as ex01,
tk02 as ex02,
tk03 as ex03,
tk04 as ex04,
tk05 as ex05,
tk06 as ex06,
tk07 as ex07,
tk08 as ex08,
tk09 as ex09,
tk10 as ex10,
tk11 as ex11,
tk12 as ex12,
tk13 as ex13,
tk14 as ex14,
tk15 as ex15
)
from common.common import (
user_input,
print_run_func,
@ -57,3 +65,36 @@ def challenges01():
exit(0)
case _:
continue
def challenges02():
select_ok = False
while not select_ok:
clear()
print(tab, '1)', ex10.tk_10.__doc__)
print(tab, '2)', ex11.tk_11.__doc__)
print(tab, '3)', ex12.tk_12.__doc__)
print(tab, '4)', ex13.tk_13.__doc__)
print(tab, '5)', ex14.tk_14.__doc__)
print(tab, '6)', ex15.tk_15.__doc__)
opcs_default(1)
selection = user_input(6)
match selection:
case 1:
print_run_func(ex10.tk_10)
case 2:
print_run_func(ex11.tk_11)
case 3:
print_run_func(ex12.tk_12)
case 4:
print_run_func(ex13.tk_13)
case 5:
print_run_func(ex14.tk_14)
case 6:
print_run_func(ex15.tk_15)
case 'v':
return
case 's':
select_ok = True
exit(0)
case _:
continue