0

次のコードでは、ボタンを作成する 2 つの方法の動作が異なります。

from Tkinter import *
def buildButton1():
    root = Tk()
    Button( root, command = lambda : foo(1) ).pack()
    Button( root, command = lambda : foo(2) ).pack()

def buildButton2():
    root = Tk()
    buttons = ( Button( root, command = lambda : foo(i) ) for i in range(2) )
    map( lambda button : button.pack(), buttons )

def foo( number ):
    print number

どちらの方法でも、表向きは同じ 2 つのボタン レイアウトを持つ Tkinter ウィンドウが作成されますが、2 つ目の例では、2 つではなく 50 個のボタンを追加した方がはるかに簡潔に見えます。foo に渡される値は、最後に反復された i です。

したがって、この場合、buildButton2 で作成されたボタンを押すと 1 が出力され、buildButton1 のボタンはそれぞれ 0 と 1 が出力されます。なぜ違いがあるのですか?buildButton2 を期待どおりに動作させる方法はありますか?

編集 これは重複した質問であり、これを構築するより正しい方法は次のように書くことであることが指摘されています。

 buttons = ( Button( root, command = lambda i=i : foo(i) ) for i in range(2) )

これにより、望ましい結果が得られます。みんなありがとう!

4

1 に答える 1

0

アプリケーションには 1 つの TK ルートのみが必要です。これは単なる例ですか、それともアプリケーションの実際のコードですか? それが実際のコードの場合、ボタンを「生成」するたびに TK ルートを取得しようとします。アプリケーションのルートは 1 つしかないため、root=TK() をメイン コードに移動する必要があります。すべてのウィンドウ、ボタン.. は、このルートの子です。

次のようなことを試すことができます:

from tkinter import *
from tkinter import ttk

    class testWnd( ttk.Frame ):  

        def createWndMain( self ):
            self.BtnLoad = ttk.Button( self, text="Load file", command=self.LoadMyFile )
            self.BtnLoad.grid( column=10, row=10, padx=8, pady=4, sticky=( S, E, W ) )

            self.BtnQuit = ttk.Button( self, text="Quit", command=self.quit )
            self.BtnQuit.grid( column=10, row=20, padx=8, pady=4, sticky=( S, E, W ) )

            self.Spacer = ttk.Frame( self, height = 12 )
            self.Spacer.grid( column = 10, row = 15, sticky = ( S, E, W ) )

            self.columnconfigure( 5, weight = 1 )
            self.rowconfigure( 5, weight = 1 )

        def LoadMyFile( self ):
            pass

        def __init__( self, tkRoot ):
            ttk.Frame.__init__( self, tkRoot )
            tkRoot.title( "My Application v 1.0" )
            tkRoot.columnconfigure( 0, weight = 1 )
            tkRoot.rowconfigure( 0, weight = 1 )
            self.tkRoot = tkRoot
            self.grid( column = 0, row = 0, sticky = ( N, S, E, W ) )
            self.createWndMain()

    tkRoot = Tk()
    myWndMain = testWnd( tkRoot )
    myWndMain.mainloop()
于 2013-10-31T05:43:32.643 に答える