前提
Pythonのtkinterを使用してComboboxを2つ作成しました。
1つ目のComboboxで選択された内容に従って、2つ目のComboboxに設定されている値を変更したいというのが今回のお題です。
サンプルソース
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#!/usr/bin/python3 from tkinter import * from tkinter import ttk list1 = ['A','B','C','D'] list2 = ['1','2','3','4'] if __name__ == '__main__': root = Tk() root.title('Sample Program') # Frame frame = ttk.Frame(root, padding=30) frame.grid() lavel1 = Label(frame,font=("MS ゴシック",10),text="Select 1 :") lavel2 = Label(frame,font=("MS ゴシック",10),text="Select 2 :") lavel1.grid(row=0,column=0,sticky=W) lavel2.grid(row=1,column=0,sticky=W) v1 = StringVar() v2 = StringVar() cb1 = ttk.Combobox( frame, textvariable=v1, values=list1, width=20) cb2 = ttk.Combobox( frame, textvariable=v2, values=list2, width=20) cb1.set(list1[0]) cb2.set(list2[0]) cb1.bind( '<<ComboboxSelected>>', cb2.set(list2[list1.index(v1.get())])) cb1.grid(row=0, column=1) cb2.bind( '<<ComboboxSelected>>', print('v2=%s' % v2.get())) cb2.grid(row=1, column=1) root.mainloop() |

このサンプルプログラムでは、「Select 1」のコンボボックスを選択しても「Select 2」の値は変化しません。
bindの中で指定しているcb2.set()がファンクションとして処理されていないようです。
結果
以下の様に変更しました。
1 2 3 4 5 6 7 8 9 10 |
cb1.bind( '<<ComboboxSelected>>', cb2.set(list2[list1.index(v1.get())])) cb1.grid(row=0, column=1) cb2.bind( '<<ComboboxSelected>>', print('v2=%s' % v2.get())) cb2.grid(row=1, column=1) |
この部分を以下の様に変更しました。
1 2 3 4 5 6 7 8 9 10 |
cb1.bind( '<<ComboboxSelected>>', lambda e: cb2.set(list2[list1.index(v1.get())])) cb1.grid(row=0, column=1) cb2.bind( '<<ComboboxSelected>>', lambda e: print('v2=%s' % v2.get())) cb2.grid(row=1, column=1) |
cb1.bindで指定しているcb2.set()をlambdaで無名関数とすることで、関数として処理されます。

cb2.baind側のprint()は処理されているのですが、敢えて同様にlambdaで無名関数とすることで、プログラムソースの統一をしていますが、敢えて変更しなくても動作します。
関数を指定するところでは、明確にdefで関数を作るか、lambdaで無名関数として定義することが望ましいということの様です。
引っ掛かったので記録として残しておきます。