2016-12-22 4 views
0

私はTkinterに取り組んでいます。私は、ユーザがボタンを押すと新しいウィンドウを開き、データベースにデータを挿入できるようにしてからテーブルを再作成し、新しいデータが挿入されたことを示します。新しいウィンドウが開き、データは実際に挿入されますが、リストは更新されず、理由もわかりません。関数を順番に実行することはできません。 Python

ボタンコード:リストなどの機能を取得し、それらを実行

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 

私は窓を生成する関数の前に移入関数を呼び出した場合、それはうまく動作しますしかし、それは私が欲しいものではない、私はユーザーが入力データを持っている後に更新したい。

ことができますかどうかは知りませんが、ここではボタンが押されたら、開いたウィンドウのコードは次のとおりです。

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 

申し訳ありませんが、いくつかの単語はポルトガル語です。

答えて

3

これは、絶対に必要でない限り、ラムダを使用しない理由の良い例です。デバッグが難しくなります。ラムダの使用を取り除き、代わりにボタンを通常の関数に結びつけることをお勧めします。これにより、デバッグコードを簡単に挿入できます。この場合、あなたの関数は、このコードを実行している

self.help(tm.FazTela(bd),self.populate()) 

これは、これを行うと同じです:

a = tm.FazTela(bd) 
b = self.populate() 
self.help(a,b) 

また、あなたは複数のルートを作成している問題を抱えています窓。 tkinterでは、常に正確に1つのルートウィンドウが必要です。 Tkの2番目のインスタンスを作成する代わりに、Toplevelのインスタンスを作成する必要があります。

ウィンドウが破棄された後にコードを実行する場合は、wait_window関数を使用できます。この関数は、指定されたウィンドウが閉じられるまで戻りません。

関連する問題