Форум сайта python.su
1
Прошу помочь, сама уже не могу даже предположить, что не так. Проблема в том, что всем кнопкам почему-то назначается одна и также функция. В словаре skillet перечислены координаты для каждой кнопки и функция, по идее все должно быть шикарно, но на практике, почему-то у всем кнопкам присваивается функция для кнопки с номером 8.
P.S кстати ещё один интересный момент, если менять названия кнопок, то функция будет браться уже из другой кнопки.
#!/usr/bin/python2.7 #coding:utf8 import Tkinter class MainWindow(Tkinter.Frame): def __init__(self, root): Tkinter.Frame.__init__(self, root, height=475, width=250) self.pack(anchor='nw') self.pack_propagate(0) self.build_widget() def build_widget(self): skillet = {u'1': [0, 0, lambda: self.test()], u'2': [1, 0, lambda: exit(0)], u'3': [2, 0, lambda: exit(0)], u'4': [3, 0, lambda: exit(0)], u'5': [4, 0, lambda: exit(0)], u'6': [0, 1, lambda: exit(0)], u'7': [1, 1, lambda: exit(0)], u'8': [2, 1, lambda: exit(50)], u'9': [3, 1, lambda: exit(0)]} # Ключ служит названием кнопки, а в значении хранятся # координаты кнопки и вызываемая при нажатии функция button = [] for i in skillet.keys(): but = Tkinter.Button(self, text=i, width=20) but.grid(row=skillet[i][0], column=skillet[i][1], padx=25, pady=5, sticky='nw') but.bind("<ButtonRelease-1>", lambda event: skillet[i][2]()) button.append(but) def test(self): print('test') if __name__ == '__main__': root = Tkinter.Tk() root.title('Test') root.geometry('475x250+0+0') main = MainWindow(root) root.mainloop()
Отредактировано masha (Май 7, 2014 13:52:58)
Офлайн
568
Во-первых, нахрена ключи словаря - строки?
Во-вторых, зачем такой цикл? Обычно делают так
for key, value in skillet.items():
args = [1, 2 ,3] for i in args: func = lambda x: x + i # Определили функцию, но пока мы ее не вызовем, ленивая лямбда тело функции не построит print(func(0)) # Тут все ожидаемо, тело функции построилось с текущим значение i funcs = [] for j in args: funcs.append(lambda x: x + j) # А вот так все функции будут одинаковые lambda x: x + 3, потому что по завершению цикла j==3, и вызывая функцию, ты получаешь в ее теле j == 3 везде после этого for f in funcs: print(f(0))
Отредактировано FishHook (Май 6, 2014 19:05:36)
Офлайн
1
FishHookЯ сюда пример тестовую версию залила, вообще там будут строки с названиями кнопок, на пример Выход, и т д По этому ключи строки.
Во-первых, нахрена ключи словаря - строки?Во-вторых, зачем такой цикл? Обычно делают так
Офлайн
1
FishHook
Подскажите пожалуйста, где можно почитать про labmda функции, точнее про эту их особенность, я раньше не встречалась с этим. Чтобы Лутц это упомянал не помню.
Офлайн
1
Подскажите пожалуйста, как мне быть если хочу вот так в цикле обработку делать и в функцию нужно передать какие-то данные, я кроме того, что функцию нужно обернуть в labmda не знаю.
Офлайн
568
mashaЯ б как-то так сделал наверное
Подскажите пожалуйста, как мне быть если хочу вот так в цикле обработку делать и в функцию нужно передать какие-то данные, я кроме того, что функцию нужно обернуть в labmda не знаю.
import tkinter root = tkinter.Tk() def callback(num): def func(event): print("clicked button {}".format(num)) return func frame = tkinter.Frame(root, width=100, height=100) for num in range(5): btn = tkinter.Button(frame, text=num) btn.bind("<Button-1>", callback(num)) btn.pack() frame.pack() root.mainloop()
Офлайн
58
FishHook
Не-не-не. Так не надо делать. Тут нужна лямбда без вариантов…
import tkinter root = tkinter.Tk() def callback(event, num): print num frame = tkinter.Frame(root, width=100, height=100) for num in range(5): btn = tkinter.Button(frame, text=num) btn.bind("<Button-1>", lambda event: callback(num)) btn.pack() frame.pack() root.mainloop()
import tkinter root = tkinter.Tk() def callback(event): print event["text"] event.widget["bg"] = "red" frame = tkinter.Frame(root, width=100, height=100) for num in range(5): btn = tkinter.Button(frame, text=num) btn.bind("<Button-1>", callback) btn.pack() frame.pack() root.mainloop()
Офлайн
58
masha
Теперь по Вашему вопросу
#coding:utf8 import Tkinter # # class MainWindow(Tkinter.Frame): # def __init__(self, root=None): Tkinter.Frame.__init__(self, root, height=475, width=250) self.pack(anchor='nw') self.pack_propagate(0) self.build_widget() # def build_widget(self): skillet = {u'1': [0, 0, lambda event: self.test()], u'2': [1, 0, lambda event: exit(20)], u'3': [2, 0, lambda event: exit(30)], u'4': [3, 0, lambda event: exit(40)], u'5': [4, 0, lambda event: exit(50)], u'6': [0, 1, lambda event: exit(60)], u'7': [1, 1, lambda event: exit(70)], u'8': [2, 1, lambda event: exit(80)], u'9': [3, 1, lambda event: exit(90)]} for i in skillet.keys(): but = Tkinter.Button(self, text=i, width=20) but.grid(row=skillet[i][0], column=skillet[i][1], padx=25, pady=5, sticky='nw') but.bind("<ButtonRelease-1>", skillet[i][2]) # @staticmethod def test(self): print('test') # if __name__ == '__main__': root = Tkinter.Tk() root.title('Test') root.geometry('475x250+0+0') main = MainWindow(root) root.mainloop()

Отредактировано 4kpt_II (Май 7, 2014 11:50:16)
Офлайн
568
FishHook
Не-не-не. Так не надо делать. Тут нужна лямбда без вариантов…
import tkinter root = tkinter.Tk() def callback(event, num): print num frame = tkinter.Frame(root, width=100, height=100) for num in range(5): btn = tkinter.Button(frame, text=num) btn.bind("<Button-1>", lambda event: callback(num)) btn.pack() frame.pack() root.mainloop()

Не-не-не. Так не надо делатьОбоснуй
Офлайн
58
Хм… Забыл. Действительно забыл. Этот фокус с лямбдой в цикле.
import Tkinter root = Tkinter.Tk() def callback(event, num): print num frame = Tkinter.Frame(root, width=100, height=100) for num in range(5): btn = Tkinter.Button(frame, text=num) btn.bind("<Button-1>", lambda event, num=num: callback(event, num)) btn.pack() frame.pack() root.mainloop()
FishHookТак не принято делать и все. Хотя и можно. Другие просто могут код не понять.
Обоснуй
Отредактировано 4kpt_II (Май 7, 2014 12:09:47)
Офлайн