所以,我正在研究Tkinter,我的目标是当用户按下按钮时,它会打开一个新窗口,他可以在数据库中插入数据,然后再次填充表格,以显示插入的新数据。新窗口打开正常,确实插入了数据,但列表没有更新,我不知道为什么。
按钮代码:
self.inserir = Button(self.container2, text="Inserir", command=lambda:self.help(tm.FazTela(bd),self.populate()))
将函数作为列表获取并运行它们的函数代码:
def help(*functions):
def func(*args, **kwargs):
return_value = None
for function in functions:
return_value = function(*args, **kwargs)
return return_value
return func
如果我在生成窗口的函数之前调用populate函数它运行得很好,但这不是我想要的,我想在用户输入数据后更新。
我不知道它是否有帮助,但这是按下按钮后打开的窗口代码:
from Tkinter import *
from database import database as db
from database import tratamentos as tr
import tkMessageBox
class TelaMenor():
def __init__(self):
self.root = None
self.OPTIONS = []
self.cor1 = '#D32F2F'
def CloseWindow(self):
self.root.destroy()
self.root = None
def SendToTR(self,nome,valor,tipo,bd):
try:
tr.ProdutosRecieve(nome,valor,tipo,bd)
except:
tkMessageBox.showerror("Erro encontrado", "Digite valores validos!")
finally:
self.CloseWindow()
def FazTela(self,bd):
if(self.root!=None):
self.CloseWindow()
self.FazTela()
else:
self.root=Tk()
# opcoes do droplist
self.OPTIONS = [
"Tipo de produto",
"Doce",
"Salgado",
"Massa",
"Bebida",
"Outro"
]
#fim
# criacao e posicao dos widgets
info = Frame(self.root)
info.grid(sticky=N+S+W+E)
salto1 = Label(info, text=" ")
salto1.grid(row=0, column=0)
nome1 = Label(info, text="Nome:")
nome1['font']=['bold']
nome1.grid(row=1, column=1, sticky=W)
nome2 = Entry(info)
nome2["width"]=40
nome2.grid(row=2, column=1)
salto2 = Label(info, text="")
salto2.grid(row=3, column=0)
valor1 = Label(info, text="Valor:")
valor1['font']=['bold']
valor1.grid(row=4, column=1, sticky=W)
valor2 = Entry(info)
valor2["width"]=40
valor2.grid(row=5, column=1)
salto3 = Label(info, text="")
salto3.grid(row=6, column=0)
variable = StringVar(info)
variable.set(self.OPTIONS[0])
droplist = apply(OptionMenu, (info, variable) + tuple(self.OPTIONS))
droplist.grid(row=7, column=1)
salto4 = Label(info, text="")
salto4.grid(row=8, column=0)
pronto = Button(info, text="Pronto", bg=self.cor1, bd=3,command=lambda: self.SendToTR(nome2.get(),valor2.get(),variable.get(),bd))
pronto['font']=['bold']
pronto['fg']='white'
pronto.grid(row=9, column=1)
salto5 = Label(info, text="")
salto5.grid(row=10, column=1)
espaco1 = Label(info, text=" ")
espaco1.grid(row=10, column=2)
#fim
# barra de "status"
status = Label(info, text="Estado: Normal", bg="white", bd=1, relief=SUNKEN, anchor=W)
status.grid(row= 11, column=0, sticky=S+W+E, columnspan=3)
#fim
# formatacao da janela
self.root.title('Cadastro do Produto')
#root.iconbitmap(r'c:\Python27\DLLs\icon.ico')
self.root.resizable(width=False, height=False)
self.root.geometry('298x276')
self.root.protocol("WM_DELETE_WINDOW",lambda: self.CloseWindow())
self.root.mainloop()
#fim
对不起,葡萄牙语中有一些单词。
答案 0 :(得分:3)
这很好地说明了为什么你不应该使用lambda,除非绝对必要:它使调试变得困难。我建议删除lambda的使用,而是将按钮绑定到正常功能。这样做可以更容易地插入调试代码。
在这种情况下,您的函数正在运行此代码:
self.help(tm.FazTela(bd),self.populate())
这与执行此操作相同:
a = tm.FazTela(bd)
b = self.populate()
self.help(a,b)
您还遇到了创建多个根窗口的问题。在tkinter中,您必须始终只有一个根窗口。您需要创建Tk
的实例,而不是创建Toplevel
的第二个实例。
如果要在窗口被销毁后执行代码,可以使用函数wait_window
,该函数在给定窗口关闭之前不会返回。