使用after()方法时,tkinter不会显示任何内容

时间:2017-03-27 07:41:54

标签: python canvas tkinter tkinter-canvas

首先,我实现了这个使用类并且运行良好的代码:

from Tkinter import *
import numpy as np
from PIL import Image,ImageTk
import time

#----------------------------------------------------------------------

class MainWindow():

    #----------------

    def __init__(self,main,pix):

        # canvas for image
        self.canvas = Canvas(main, width=424, height=424)
        self.canvas.grid(row=0, column=0)

        # images
        self.im=Image.fromarray(pix.astype('uint8'))
        self.photo = ImageTk.PhotoImage(image=self.im)
        self.my_images = self.photo

        self.my_image_number = 0

        # set first image on canvas
        self.image_on_canvas = self.canvas.create_image(0, 0, anchor = NW, image = self.my_images )
        self.i=0
        self.j=0
        main.after(1,self.onButton,main,pix)# button to change image
        main.update()
    #----------------

    def onButton(self,main,pix):
        print self.i,self.j
        if self.j==100:
            return
        pix[self.i][self.j]=255-pix[self.i][self.j]
        self.i+=1
        if self.i==100:
            self.i=0
            self.j+=1
        self.im=Image.fromarray(pix.astype('uint8'))
        self.photo = ImageTk.PhotoImage(image=self.im)
        self.my_images = self.photo
        self.canvas.itemconfig(self.image_on_canvas, image = self.my_images)
        main.after(1,self.onButton,main,pix)
    else:
        main.after(0,self.onButton,main,pix)

#----------------------------------------------------------------------

root = Tk()
pix=np.array([[(i,j,255) for i in range(256)] for j in range(255,-1,-1)])
x=MainWindow(root,pix)
root.mainloop()

后来我尝试在没有类的情况下使用相同的函数,它看起来像这样:

from Tkinter import *
import numpy as np
from PIL import Image,ImageTk
import time

def onButton(main,pix):
        global i,j
        if j==100:
            return
        pix[i][j]=255-pix[i][j]
        i+=1
        if i==100:
            i=0
            j+=1
        im=Image.fromarray(pix.astype('uint8'))
        photo = ImageTk.PhotoImage(image=im)
        my_images = photo
        canvas.itemconfig(image_on_canvas, image = my_images)
        main.after(1,onButton,main,pix)
    else:
        main.after(0,onButton,main,pix)

root = Tk()
pix=np.array([[(i,j,255) for i in range(256)] for j in range(255,-1,-1)])
canvas = Canvas(root, width=424, height=424)
canvas.grid(row=0, column=0)
im=Image.fromarray(pix.astype('uint8'))
photo = ImageTk.PhotoImage(image=im)
image_on_canvas = canvas.create_image(0, 0, anchor = NW, image = photo )
i,j=0,0
root.after(1,onButton,root,pix)# button to change image
print "hi"
root.mainloop(f i==100:
            i=0
            j+=1
        im=Image.fromarray(pix.astype('uint8'))
        photo = ImageTk.PhotoImage(image=im)
        my_images = photo
        canvas.itemconfig(image_on_canvas, image = my_images)
        main.after(1,onButton,main,pix)
    else:
        main.after(0,onButton,main,pix)

root = Tk()
pix=np.array([[(i,j,255) for i in range(256)] for j in range(255,-1,-1)])
canvas = Canvas(root, width=424, height=424)
canvas.grid(row=0, column=0)
im=Image.fromarray(pix.astype('uint8'))
photo = ImageTk.PhotoImage(image=im)
image_on_canvas = canvas.create_image(0, 0, anchor = NW, image = photo )
i,j=0,0
root.after(1,onButton,root,pix)# button to change image
print "hi"
root.mainloop()

为什么这不起作用?这是我第一次使用tkinter,所以我可能错过了一些至关重要的东西。我需要改变什么?

1 个答案:

答案 0 :(得分:0)

我很好奇为什么你需要在没有课程的情况下实现这样的事情,但首先让我们来看看你的问题,即OnButton函数。

您已经定义了全局变量ij。但其他人怎么样? 您尝试变异(并保持值)的所有变量也必须声明为全局变量!这是问题的根源,对于“为什么不起作用”这个问题的答案 - @PM 2Ring可以很好地参考photoimage文档。

  

注意:当Python对垃圾收集PhotoImage对象时(例如,当您从一个将图像存储在局部变量中的函数返回时),即使Tkinter小部件正在显示该图像,该图像也会被清除。

try:
    from tkinter import *
except ImportError:
    from Tkinter import *

import numpy as np
from PIL import Image,ImageTk


def onButton():
    global i, j, photo     #, pix

    print(i, j)
    if j == 100:
        return
    pix[i][j] = 255-pix[i][j]
    i += 1
    if i == 100:
        i = 0
        j += 1
        photo = ImageTk.PhotoImage(image=Image.fromarray(pix.astype('uint8')))
        canvas.itemconfig(image_on_canvas, image=photo)
        root.after(1, onButton)
    else:
        root.after(0, onButton)


root = Tk()
pix=np.array([[(i, j, 255) for i in range(256)] for j in range(255, -1, -1)])
canvas = Canvas(root, width=424, height=424)
canvas.grid(row=0, column=0)
photo = ImageTk.PhotoImage(image=Image.fromarray(pix.astype('uint8')))
image_on_canvas = canvas.create_image(0, 0, anchor=NW, image=photo)
i, j = 0, 0
root.after(1, onButton)     # button to change image
print("hi")
root.mainloop()

如果在函数外部不需要这个变量 - 那么make'em local并将所有相关代码移动到函数中!

毕竟,请花点时间阅读this文章。也许你改变了对类的看法(以及关于通配符导入)。