2016-05-13 84 views
1

私のtkinterアプリケーションは、呼び出されたウィンドウ(クラスMyDialog)からlistboxの選択された項目を呼び出し元のウィンドウ(クラス)。 wait_window()を使用しないと、空のリストが返されます。 wait_window()を使用するとエラーメッセージが表示されます。 wait_window()はcurselection()メソッドをブロックしているようです。適切なリターンのために何を変更する必要がありますか?tkinterでwait_window()を使用しているときにリストボックスの選択された項目を返す方法

以下の例は、this answerの変更バージョンです。

import tkinter as tk 

class MyDialog(object): 
    def __init__(self, parent): 
     self.toplevel = tk.Toplevel(parent) 

     choices = ("one", "two","three") 
     names = tk.StringVar(value=choices) 

     label = tk.Label(self.toplevel, text="Pick something:") 
     self.listbox = tk.Listbox(self.toplevel, listvariable=names, height=3, 
      selectmode="single", exportselection=0) 
     button = tk.Button(self.toplevel, text="OK", command=self.toplevel.destroy) 

     label.pack(side="top", fill="x") 
     self.listbox.pack(side="top", fill="x") 
     button.pack() 

    def show(self): 
     self.toplevel.wait_window() 

     value = self.listbox.curselection() 
     return value 

class Example(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 

     self.button = tk.Button(self, text="Click me!", command=self.on_click) 
     self.label = tk.Label(self, width=80) 
     self.label.pack(side="top", fill="x") 
     self.button.pack(pady=20) 

    def on_click(self): 
     result = MyDialog(self).show() 
     self.label.configure(text="your result: %s" % result) 

if __name__ == "__main__": 
    root = tk.Tk() 
    Example(root).pack(fill="both", expand=True) 
    root.mainloop() 

答えて

1

wait_window待機未亡人がとなるまでは、を破壊しました。そして、それは破壊されているので、ウィジェットから情報を引き出すことはできません。

データが変更されたときに変数に保存するバインドを設定する必要があります。これにより、ウィジェットが破棄された後にデータを取得できるようになります。

+0

私は試してみます。しかし、なぜ元の例のようなオプションメニューでリターンが機能するのですか? – AnBe

+0

@AnBe:オプションメニューは、ウィジェットが破棄されたときに_not_破壊された変数に値を格納するためです。 –

0

ブライアン・オークリーの答えは、以下に掲載されたソリューションに私を導いた。どうもありがとうございました!

import tkinter as tk 

class MyDialog(object): 
    def __init__(self, parent): 
     self.toplevel = tk.Toplevel(parent) 

     choices = ("one", "two","three") 
     names = tk.StringVar(value=choices) 

     label = tk.Label(self.toplevel, text="Pick something:") 
     self.listbox = tk.Listbox(self.toplevel, listvariable=names, height=3, 
      selectmode="single", exportselection=0) 
     button = tk.Button(self.toplevel, text="OK", command=self.toplevel.destroy) 

     label.pack(side="top", fill="x") 
     self.listbox.pack(side="top", fill="x") 
     button.pack() 

     # add binding 
     self.listbox.bind('<<ListboxSelect>>', self.getSelection) 

    # function associated with binding 
    def getSelection(self, event): 
     widget = event.widget 
     selection=widget.curselection() 
     self.value = widget.get(selection[0]) 

    # separate function for wait_window and the return of the selection 
    def returnValue(self): 
     self.toplevel.wait_window() 
     return self.value 

class Example(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 

     self.button = tk.Button(self, text="Click me!", command=self.on_click) 
     self.label = tk.Label(self, width=80) 
     self.label.pack(side="top", fill="x") 
     self.button.pack(pady=20) 

    def on_click(self): 
     result = MyDialog(self).returnValue() 
     self.label.configure(text="your result: %s" % result) 

if __name__ == "__main__": 
    root = tk.Tk() 
    Example(root).pack(fill="both", expand=True) 
    root.mainloop() 
関連する問題