Tkinter图像更新图像+ lambda错误

时间:2017-12-15 02:04:47

标签: python user-interface tkinter ttk

最近我基本上自学了Tkinter。我已经在这个项目上工作了大约一个星期了,我觉得它很顺利。今天,当我正在研究它时,我得到了这个代码,在成功运行时设置了GUI。但是,当我尝试通过Combobox更改图像时,它会失败并给我以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
TypeError: <lambda>() takes 0 positional arguments but 1 was given

快速搜索后,我发现使用lambda x:可以解决此错误。进行此更改后,GUI将正常启动,但图像仍然不会更改,实际上,如果从第一个Combobox中选择了一个项目,则第二个面板会出现故障并删除图像。完全删除'lambda'会导致面板根本无法启动。基本上,我想知道导致这些故障的原因以及如何让我的图像更新。

from tkinter import *
from tkinter.ttk import *
from PIL import Image, ImageTk
import os

class App(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        parent.title('Vainglory DMG Calculator | BETA')
        self.dyn_panel = []
        self.dyn_combobox = []
        self.dyn_image_path = ['', '']
        self.dyn_img = ['', '']
        self.cwd = os.getcwd()
        self.hero_list = ('Adagio', 'Alpha', 'Ardan', 'Baptiste', 'Baron', 'Blackfeather', \
                          'Catherine', 'Celeste', 'Churnwalker', 'Flicker', 'Fortress', \
                          'Glaive', 'Grace', 'Grumpjaw', 'Gwen', 'Idris', 'Joule', \
                          'Kestrel', 'Koshka', 'Krul', 'Lance', 'Lorelai', 'Lyra', 'Ozo', \
                          'Petal', 'Phinn', 'Reim', 'Reza', 'Ringo', 'Rona', 'Samuel', \
                          'SAW', 'Skaarf', 'Skye', 'Taka', 'Varya', 'Vox')
        for i in range(2):
            self.create_hero_combo_box(parent, i)
            self.set_image(i)            
            self.create_hero_panel(parent, self.dyn_img[i], i)

    def create_hero_panel(self, window, img, index):
        self.dyn_panel.append(Label(window, image=img))
        self.dyn_panel[index].grid(row=0, column=index*2)

    def create_hero_combo_box(self, window, index):
        self.dyn_combobox.append(Combobox(window, values=(*self.hero_list,)))
        self.dyn_combobox[index].grid(row=1, column=index*2)
        self.dyn_combobox[index].set(self.hero_list[0])

    def set_image(self, index):
        self.dyn_image_path[index] = (self.cwd + '/img/heroes/' + self.dyn_combobox[index].get().lower() + '.png')
        self.dyn_img[index] = ImageTk.PhotoImage(Image.open(self.dyn_image_path[index]))

    def update(self, index):
        self.dyn_panel[index].configure(image=self.set_image(index))

if __name__ == '__main__':
    root = Tk()
    app = App(root)
    for i in range(2):
        app.dyn_combobox[i].bind('<<ComboboxSelected>>', lambda x: app.update(i))
    root.mainloop()

1 个答案:

答案 0 :(得分:-1)

每个小部件都有方法update(),但您在update()中创建了App(Frame),因此您可以替换它 - 这可能会产生问题。使用与update()

不同的名称