python - 在 python/tkinter 上将值从子窗口传递到父窗口
问题描述
我一直在尝试学习 Python 语言以获得乐趣,并决定最好通过一个项目来完成它。因为我在一家啤酒厂工作,所以我认为创建一个简单的 GUI 来显示工厂中的所有罐以及它所持有的每种啤酒及其当前状态会很酷。如果我双击一个坦克,它会弹出一个新窗口,允许我编辑坦克信息,但我无法让来自孩子的信息显示在父窗口上(更具体地说,我想更改父母列表中子项组合框中的项目)。这是一张基本上显示我想要完成的图像的图像:
我认为也许这些值被正确传递到列表中,但它们没有被更新到要显示的对应 Widget。我尝试调用.update()
,.after()
和.mainloop()
我的函数,但没有任何改变。
我尝试检查其他答案,但我实际上希望有一种方法可以在不求助于类的情况下解决这个问题,因为我还不太了解它们。这是我能想到的最简单的最小版本的代码:
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
def click_duplo_tfm(event): # recognizes double-click on tanks and opens the specific window
if event.widget.extra == 'Widget TFM01':
abrir_janela('01', 1)
elif event.widget.extra == 'Widget TFM02':
abrir_janela('02', 2)
def salvar_alteracoes():
print('THIS FUNCTION IS SUPPOSED TO PASS CHANGES TO PARENT WINDOW')
def abrir_janela(num_tfm, ref): # opens a new window to alter tank info
def manter_selecao_ceva(event):
global ceva_tqs
ceva_tqs[referencia] = opcao_ceva.get()
print(ceva_tqs[referencia])
def manter_selecao_status(event):
global status_tqs
status_tqs[referencia] = opcao_status.get()
print(status_tqs[referencia])
referencia = int(ref)
janela = tk.Toplevel(adega_grande)
janela.title('TFM-' + num_tfm)
janela.geometry('550x300')
tfm = Image.open(img_tqs[referencia])
tfm.thumbnail((300, 300), Image.ANTIALIAS)
photo_tfm = ImageTk.PhotoImage(tfm, master=janela)
label_tfm = tk.Label(image=photo_tfm, borderwidth=0, highlightthickness=0, master=janela)
label_tfm.image = photo_tfm
label_tfm.grid(column=1, rowspan=20, row=1)
qual_tfm = tk.Label(master=janela, text='TFM-' + num_tfm, font='Arial 24 bold')
qual_tfm.grid(column=2, row=1)
ceva = tk.Label(master=janela, text='Cerveja: ', font='Arial 20 bold')
ceva.grid(column=2, row=2, sticky='W')
ceva_selecionada = 'Ceva selecionada'
opcao_ceva = ttk.Combobox(master=janela, values=cervs_factory, state='readonly', textvariable=ceva_selecionada)
opcao_ceva.grid(column=3, row=2)
opcao_ceva.bind("<<ComboboxSelected>>", manter_selecao_ceva)
status = tk.Label(master=janela, text='Status: ', font='Arial 20 bold')
status.grid(column=2, row=3, sticky='W')
status_selecionado = 'Status selecionado'
opcao_status = ttk.Combobox(master=janela, values=('Fermentando', 'Maturando'), state='readonly', textvariable=status_selecionado)
opcao_status.grid(column=3, row=3)
opcao_status.bind("<<ComboboxSelected>>", manter_selecao_status)
botao_salvar_alteracoes = tk.Button(master=janela, text="Salvar alterações no TFM", command=salvar_alteracoes)
botao_salvar_alteracoes.grid(column=2, columnspan=2, row=4)
# creates main window and tabs (there are 22 smaller tanks to be added later on second tab)
gui = tk.Tk()
gui.configure(background="white")
gui.title("Acompanhamento de adegas")
abas = tk.ttk.Notebook(gui)
adega_grande = tk.Frame(abas)
adega_pequena = tk.Frame(abas)
abas.add(adega_grande, text='Adega Grande')
abas.add(adega_pequena, text='Adega pequena')
abas.grid()
# list of all kinds of beer produced in the factory
cervs_factory = ('VAZIO', 'Weiss', 'Vienna Lager')
# list of images to show on the tanks
img_tqs = ["",
"tq cheio Beer 1.png", # TFM-01
"tq cheio Beer 2.png", # TFM-02
] # TFM-12
# list of which beer is currently on each tank
ceva_tqs = ["",
cervs_factory[1], # TFM-01
cervs_factory[2]] # TFM-02
# list of tank current status Fermenting/Maturing
status_tqs = ["",
'Fermentando', # TFM-01
'Maturando', # TFM-02
] # TFM-12
# ~~~~ TFM's Adega Grande ~~~~ #
font_titulo_tfm = 'Arial 14 bold' # altera fonte e tamanho dos títulos dos TFM's
font_cerv_e_status = 'Arial 12 bold' # altera fonte e tamanho do tipo de cerveja e status dos TFM's
tamanho_img_tqs = (250, 250) # altera o tamanho das imagens dos TFM's, só considera o menor valor
tfm01 = Image.open(img_tqs[1])
tfm01.thumbnail(tamanho_img_tqs, Image.ANTIALIAS)
photo_tfm01 = ImageTk.PhotoImage(tfm01)
label_tfm01 = tk.Label(adega_grande, image=photo_tfm01, borderwidth=0, highlightthickness=0)
label_tfm01.grid(column=1, row=0)
legenda_tfm01 = tk.Label(adega_grande, text='TFM-01', font=font_titulo_tfm)
legenda_tfm01.grid(column=1, row=1)
ceva01 = tk.Label(adega_grande, text=ceva_tqs[1], font=font_cerv_e_status)
ceva01.grid(column=1, row=2)
status01 = tk.Label(adega_grande, text=status_tqs[1], font=font_cerv_e_status, fg='green')
status01.grid(column=1, row=3)
label_tfm01.bind('<Double-Button-1>', click_duplo_tfm)
label_tfm01.extra = "Widget TFM01"
tfm02 = Image.open(img_tqs[2])
tfm02.thumbnail(tamanho_img_tqs, Image.ANTIALIAS)
photo_tfm02 = ImageTk.PhotoImage(tfm02)
label_tfm02 = tk.Label(adega_grande, image=photo_tfm02, borderwidth=0, highlightthickness=0)
label_tfm02.grid(column=2, row=0)
legenda_tfm02 = tk.Label(adega_grande, text='TFM-02', font=font_titulo_tfm)
legenda_tfm02.grid(column=2, row=1)
ceva02 = tk.Label(adega_grande, text=ceva_tqs[2], font=font_cerv_e_status)
ceva02.grid(column=2, row=2)
status02 = tk.Label(adega_grande, text=status_tqs[2], font=font_cerv_e_status, fg='blue')
status02.grid(column=2, row=3)
label_tfm02.bind('<Double-Button-1>', click_duplo_tfm)
label_tfm02.extra = "Widget TFM02"
abas.mainloop()
如果我的问题/代码太长,我希望能被原谅,我对编码很陌生,这是我第一次寻求帮助。英语也不是很流利,但我想你们明白我的问题所在。提前感谢您的任何见解。
解决方案
如果您使用类确实会容易得多,但使用您当前的方法仍然可行。
基本上,您需要首先将您的品牌/状态标签存储到一个容器(如 a list
),然后当您生成一个Toplevel
小部件时,传递一个索引,以便您知道需要修改哪些标签。下面是一个最小样本:
import tkinter as tk
from tkinter import ttk
from itertools import cycle
root = tk.Tk()
brands = ('VAZIO', 'Weiss', 'Vienna Lager')
status = ("Fermenting","Maturing")
beer_factory = cycle(brands)
beer_status = cycle(status)
beer = []
for i in range(6):
a = tk.Label(root,text=f"TFM-0{i+1}",width=20)
a.grid(row=0,column=i)
b = tk.Label(root, text=next(beer_factory))
b.grid(row=1, column=i)
c = tk.Label(root, text=next(beer_status))
c.grid(row=2, column=i)
a.bind('<Double-Button-1>', lambda e, i=i: toplevel(e,i))
beer.append([a,b,c])
def toplevel(event, i):
top = tk.Toplevel()
tk.Label(top,text="Beer factory").grid(row=0,column=0)
tk.Label(top, text="Status").grid(row=1, column=0)
com1 = ttk.Combobox(top,values=brands,state="readonly")
com1.set(beer[i][1]["text"])
com1.grid(row=0,column=1)
com2 = ttk.Combobox(top,values=status,state="readonly")
com2.set(beer[i][2]["text"])
com2.grid(row=1,column=1)
def finish():
beer[i][1].config(text=com1.get())
beer[i][2].config(text=com2.get())
top.destroy()
tk.Button(top,text="Finish",command=finish).grid(row=3,column=0,columnspan=2)
root.mainloop()
该<Double-Button-1>
事件绑定到标签 TFM-0X。
推荐阅读
- azure - Azure Service Fabric 自动升级
- java - 我应该在 DB 中为 UserAddress 助手类 Java、Hibernate、Postgres 创建一个单独的表吗?
- java - Spring Security OAuth2 不适用于承载授权(Rest api 请求)
- wordpress - 需要减少 Wordpress 帖子摘录
- javascript - 自定义 CSS 随机应用
- react-native - react-native-music-control 不听任何事件
- javascript - 正则表达式替换多个非空行
- c# - 如何在 C# 中检查和更改数组中的值?
- html - 如何应用根文件夹中的css文件
- encryption - 如何从 Jmeter 请求正文中提取动态值?