Tkinter:更新无法直接访问的标签中的图像

时间:2019-03-20 22:10:59

标签: python user-interface tkinter python-imaging-library

在我的GUI中,我想显示根据某些值而变化的图像。图像将在self.img1self.img2之间变化。我为容器和页面创建了单独的类。容器的定义如下:

class Gui(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)
        container = Frame(self)
        container.pack(side="top", fill = "both", expand = TRUE)
        container.grid_rowconfigure(0, weight = 1)


        self.MyReading = StringVar()

        self.redpic = Image.open("red.png")
        self.redpic = self.redpic.resize((100,100), Image.ANTIALIAS)
        self.greenpic = Image.open("green.png")
        self.greenpic = self.greenpic.resize((100,100), Image.ANTIALIAS)
        self.img1 = ImageTk.PhotoImage(self.redpic)
        self.img2 = ImageTk.PhotoImage(self.greenpic)

        self.frames={}

        for F in (StartPage, PageOne):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row = 0, column = 0, sticky = "nsew")

        self.show_frame(StartPage)


    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

显示图像的页面:

class StartPage(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self,parent)

        label = Label(self, text="StartPage")
        label.grid()
        label1 = Label(self, textvariable = controller.MyReading)
        label1.grid();

        self.label4 = Label(self, image = controller.img1)
        self.label4.grid();
        self.label4.image = controller.img1

        button1 = Button (self, text = "Show PageOne", command = lambda: controller.show_frame(PageOne))
        button1.grid()

它当前正在显示img1。现在,要实例化GUI:

root = Gui()
update_reading()
root.mainloop()

update_reading()更新我用StringVar()定义的其他标签。我想知道如果我只能实例化/获得对label4的访问权限,该如何更新Gui()(显示图像)?我只知道我可以通过label4来更改configure()。图片是否有textvariable的等效项?

编辑:我忘记了要实现的逻辑。基本上是:

If foo == TRUE:
  --change the image to img1--
else:
  --change the image to img2--

对于foo之外的某些Gui

EDIT2 :按照上一条注释的逻辑,我对Gui中的代码做了一些小的更改:

class Gui(Tk):
  def __init__(self, *args, **kwargs):
    self.ColorVar = DoubleVar()

StartPage()中,更改为:

class StartPage(Frame):
  def __init__(self, parent, controller):
    controller.ColorVar.trace("w",self.IdkChief(controller))

  def IdkChief(self, controller):
        global val1
        if float(val1) < 2.50 :
            self.label4.configure(image = controller.img2)
            self.label4.image = controller.img2
        else:
            self.label4.configure(image = controller.img1)
            self.label4.image = controller.img1

然后在ColorVar中定义update_reading()的更改,如下所示:

def update_reading():
    global val1
    root.ColorVar.set(val1)
    root.after(100,update_reading)

val1是一个不断变化的浮点值。我决定将其从布尔逻辑更改为浮点逻辑,以提高灵活性。然后会抛出一个通用错误

  

Tkinter回调Traceback中的异常(最近一次调用最后一次):
  文件   “ C:\ Users \ AppData \ Local \ Programs \ Python \ Python37 \ lib \ tkinter__init __。py”,   第1705行,在致电       返回self.func(* args)TypeError:“ NoneType”对象不可调用

此错误将重复发生,直到关闭GUI。

1 个答案:

答案 0 :(得分:0)

您可以使用tkinter变量trace函数来设置一个在变量更新时执行的回调函数。在回调函数中,您可以根据变量的值更新标签。

下面是实现您的目标的示例代码块(基于您发布的代码设计):

class Gui:
    def __init__(self, *args, **kwargs):
        ...
        self.ColorVar = DoubleVar()
        ...

class StartPage(Frame):
    def __init__(self, parent, controller):
        ...
        # register a callback to be executed whenever variable is modified
        controller.ColorVar.trace('w', lambda *args: self.IdkChief(controller))

    def IdkChief(self, controller):
        img = controller.img1 if controller.ColorVar.get() < 2.5 else controller.img2
        self.label4.config(image=img)