为什么在类中使用tkinter画布时不更新

0 投票
1 回答
647 浏览
提问于 2025-04-18 13:10

我正在写一个小程序,想在画布上画点东西。这段代码对我来说是有效的;

import tkinter as tk
from PIL import Image, ImageTk
from l_systems import Lindenmayer

if __name__ == "__main__":

    root = tk.Tk()
    root.title("Draw Shapes with L-Equations")

    cv = tk.Canvas(width=600, height=600, bg='white')
    cv.pack()

    image1 = Image.new("RGB", (600, 600), (255,255,255))
    koch = Lindenmayer(image1)

    koch.init(
        iterations = 6,
        angle      = 25,
        axiom      = "---X",
        rules      = {"X":"2F-[1[X]+3X]4+F[3+FX]-X", "F":"FF"},
        constants   = "X") # This creates a drawing on PIL image

    # Canvas.create_image expects a PhotoImage
    photo = ImageTk.PhotoImage(image1) 
    cv.create_image((300,300), image=photo)


    root.mainloop()

但是,我想把我的tkinter应用程序整理成一个类,所以我尝试了这段代码,

class main(tk.Frame):

    w = 600
    h = 600

    def __init__(self,parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)

        self.parent = parent
        self.cv = tk.Canvas(width=self.w, height=self.h, bg='white')
        self.cv.pack()

        self.render_image()

    def render_image(self):
        image1 = Image.new("RGB", (self.w, self.h), (255,255,255))
        koch = Lindenmayer(image1)

        koch.init(
            iterations = 6,
            angle      = 25,
            axiom      = "---X",
            rules      = {"X":"2F-[1[X]+3X]4+F[3+FX]-X", "F":"FF"},
            constants   = "X"
        )

        photo = ImageTk.PhotoImage(image1)
        self.cv.create_image((self.w/2,self.h/2), image=photo)

if __name__ == "__main__":

    root = tk.Tk()
    root.title("Draw Shapes with L-Equations")
    app = main(root).pack()
    root.mainloop()

在第二种情况下,我在画布上什么都看不见。只有一片白色的背景。我该怎么解决这个问题呢?

1 个回答

1

PhotoImage 在类和函数中可能会出现问题。垃圾回收器 可能会把它从内存中删除。


编辑:

我可以检查这个(因为我有 Lindenmayer 模块),但你的类可以这样写:

几乎所有内容都在类里面。

类的名称通常应该使用 CapWords 这种命名方式。 - 参见 PEP 8 -- Python 代码风格指南。甚至 Stack Overflow 也使用这个规则来识别代码中的类,并用浅蓝色显示。

import tkinter as tk
from PIL import Image, ImageTk
from l_systems import Lindenmayer

class Main(tk.Frame):

    def __init__(self,parent, *args, **kwargs):

        tk.Frame.__init__(self, parent, *args, **kwargs)

        self.w = 600
        self.h = 600

        self.parent = parent

        self.parent.title("Draw Shapes with L-Equations")

        self.cv = tk.Canvas(width=self.w, height=self.h, bg='white')
        self.cv.pack()

        self.render_image()

        self.parent.pack()

    def render_image(self):

        image1 = Image.new("RGB", (self.w, self.h), (255,255,255))
        koch = Lindenmayer(image1)

        koch.init(
            iterations = 6,
            angle      = 25,
            axiom      = "---X",
            rules      = {"X":"2F-[1[X]+3X]4+F[3+FX]-X", "F":"FF"},
            constants   = "X"
        )

        self.photo = ImageTk.PhotoImage(image1)
        self.cv.create_image((self.w/2,self.h/2), image=self.photo)

    def run(self):
        self.parent.mainloop()

if __name__ == "__main__":

    Main(tk.Tk()).run()

撰写回答