3

我正在尝试学习一些 Python 和 Tkinter。下面的示例代码旨在在屏幕上放置两个窗口、几个按钮和一个带有图像和一些线条的画布。

窗口和按钮看起来很好,但是我没有看到画布图像或画布线条。我会很感激一些帮助来弄清楚我的画布显示需要什么。

from Tkinter import *
import Image, ImageTk

class App:

    def __init__(self, master):

    def scrollWheelClicked(event):
        print "Wheel wheeled"

    frame = Frame(master)
    frame.pack()
    self.button = Button(frame, text = "QUIT", fg="red", command=frame.quit)
    self.button.pack(side=LEFT)

    self.hi_there = Button(frame, text="Hello", command=self.say_hi)
    self.hi_there.pack(side=LEFT)

    top = Toplevel()
    canvas = Canvas(master=top, width=600, height=600)

    image = Image.open("c:\lena.jpg")
    photo = ImageTk.PhotoImage(image)
    item = canvas.create_image(0, 0, image=photo)

    canvas.create_line(0, 0, 200, 100)
    canvas.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
    canvas.create_rectangle(50, 25, 150, 75, fill="blue")

    canvas.pack

    testBtn = Button(top, text = "test button")
    testBtn.pack()

def say_hi(self):
    print "hi there everyone!"

root = Tk()
app = App(root)
root.mainloop()
4

2 回答 2

7

我解决了这个问题:

self.photo = ImageTk.PhotoImage(image)
self.item = canvas.create_image(0, 0, image=self.photo)

对 ImageTk 实例的引用必须存储在某个地方,否则当您的App.__init__()方法返回时,它将被垃圾收集,并且画布将无法显示它。(Tkinter 不保留对图像的引用。)

保持对它的引用的一种方法是将其存储在“self.photo”或名为“photo”的变量中,或者像大多数程序员对常量变量所做的那样(不改变的变量,例如 'TEN = 10' ), 'PHOTO = PhotoImage(...)' 为什么...我不知道。导入模块“gc”(Python 3 的垃圾收集模块,内置)并运行 gc.disable() 不起作用。(如果你想试试:https ://docs.python.org/3/library/gc.html )

于 2010-10-27T19:45:18.220 回答
4

在画布对象上调用 pack 时需要括号。否则,您只是指的是函数对象,而不是调用它。

例如:

canvas.pack()

另一个例子:

>>>def hello():
...    print "hello world"
...    return

>>>hello 返回函数引用(函数 hello at 0x....)

>>>hello()实际调用了hello函数

于 2010-02-08T18:55:24.567 回答