Tkinter在画布上更改图像

时间:2014-05-31 12:06:59

标签: python tkinter

所以我写了一些代码,为数学学生显示某个主题的随机问题。模块定义显示所选主题的初始图像。然后在相应的按钮下使用下一个问题和标记方案定义。下一个问题一个正常但是因为标记方案定义链接了模块定义问题没有更新。导致只显示第一个问题的标记方案。如何使用下一个问题按钮更新它?

def module(mod):
    def mark_scheme():
        questions.delete('all')
        scheme=random_question.replace('.GIF', 'MS.GIF')
        answer=ImageTk.PhotoImage(file=scheme)
        lab1.configure(image=answer)
        lab1.image=answer
        lab1.pack(fill=BOTH, expand=1)
        return

    def next_question():

        questions.delete('all')
        random_question=random.choice(mod)
        question=ImageTk.PhotoImage(file=random_question)
        lab1.configure(image=question)
        lab1.image=question
        lab1.pack(fill=BOTH, expand=1)
        return

    questions=Canvas(root)
    questions.pack(fill=BOTH, expand=1)
    lab1=Label(questions)
    random_question=random.choice(mod)                            
    question=ImageTk.PhotoImage(file=random_question) 
    lab1.configure(image=question)
    lab1.image=question
    lab1.pack(fill=BOTH, expand=1)
    button1=Button(root, text='Next Question', command=next_question).pack()
    button2=Button(root, text='Mark Scheme', command=mark_scheme).pack()
    return

1 个答案:

答案 0 :(得分:0)

此处使用Canavas小部件是不必要的,因为只需一个简单的Label即可完成所有这些工作。类似地,您选择使用闭包来包装代码并停止对垃圾收集的图像引用有点不寻常。你可能会更好地转向如下所示的简单类结构。

下面的示例显示了如何在Tkinter中更新标签图像。下面的代码不是随机选择图像,而是循环遍历当前目录中的所有PNG文件。

import Tkinter as tk
from PIL import ImageTk
import glob

IMAGES = glob.glob("*.png")
DEFAULT_IMAGE = IMAGES[0]

class QuestionWindow(tk.Frame):
    def __init__(self,parent):
        self.parent=parent
        tk.Frame.__init__(self)
        self.init_window()

    def update_image(self,move=0):
        """
        move = +1 jumps to the next image in the sequence
        move = -1 skips back to the previous image in the sequence
        move = +2 jumps... you get it.
        """
        self.img_idx += move
        fname = IMAGES[self.img_idx%len(IMAGES)]

        # here generate the image and make sure a reference is 
        # kept in the form of a class attribute.
        self.img = ImageTk.PhotoImage(file=fname)

        # set the label image.
        self.question_lbl.configure(image=self.img)

    def init_window(self):
        self.img_idx = 0

        # choose a default image for startup
        self.img = ImageTk.PhotoImage(file=DEFAULT_IMAGE)

        # This is the question label that will contain the image
        self.question_lbl = tk.Label(self,image=self.img)
        self.question_lbl.pack(anchor=tk.N, side=tk.TOP, fill=tk.BOTH, expand=1)

        # These are the next and prev buttons. Note that they are using lambdas to
        # generate partial functions that call update_image,
        self.next_btn = tk.Button(self,text="Next",command=lambda:self.update_image(+1))
        self.next_btn.pack(anchor=tk.S,side=tk.RIGHT)

        self.prev_btn = tk.Button(self,text="Previous",command=lambda:self.update_image(-1))
        self.prev_btn.pack(anchor=tk.S,side=tk.LEFT)


if __name__ == "__main__":
    root = tk.Tk()
    qw = QuestionWindow(root)
    qw.pack()
    root.mainloop()

根据正在显示的图像,窗口将根据情况调整大小,但可以通过修复窗口几何图形来更改。