2012-06-27 5 views
2

Я пытаюсь создать скрипт, который позволит мне динамически обновлять объект изображения, а затем отправлять обновленное изображение в виджет Tkinter Canvas. Код здесь - прототип кода, просто чтобы ослабить основы. Цель здесь - поместить синий пиксель на изображение, отображаемое холстом, в месте щелчка.Как обновить изображения на холсте Tkinter?

Здесь что-то очень странное. Я использую Wing IDE, и если я запустил этот код через отладчик, с точкой останова в любой строке функции woohoo, а затем продолжить выполнение после попадания точки останова, код работает точно так, как ожидалось, - синяя пиксель на изображении. Если я запускаю код нормально или через отладчик без точек останова, изображение никогда не обновляется. Это приводит меня к выводу, что происходит некоторое внутреннее волшебство, на которое у меня нет надежды на понимание без помощи.

Мне бы очень хотелось узнать, как это сделать (или каким-либо образом, я думаю), и если кто-то может объяснить мне, что происходит под капотом, это было бы действительно круто. Благодарю.

from Tkinter import * 
from PIL import Image, ImageTk 

def woohoo(event): 

    original.putpixel((event.x,event.y),(0,0,255)) 

    newpic = ImageTk.PhotoImage(original) 
    c.create_image((0,0),image=newpic, anchor="nw") 


main = Tk() 
c = Canvas(main, width=300, height=300) 
main.geometry("300x300+0+0") 
c.pack() 

original = Image.open("asc.bmp") 
picture = ImageTk.PhotoImage(original) 
c.create_image((0,0),image=picture, anchor="nw") 

c.bind("<Button-1>", woohoo) 

main.mainloop() 

ответ

3

Я предполагаю, что вы создаете новое изображение в функции. Ссылка на изображение является локальной переменной. Когда функция выходит, эта ссылка представляет собой сбор мусора, который приводит к уничтожению нового изображения. Скорее всего, работает в интерактивном режиме вызывает сборщик мусора для запуска по-разному

+0

Я чувствую себя очень глупо делать эту ошибку. Я привык создавать объекты из каждого проекта, с членами, которые имеют практически глобальный масштаб, так что, возможно, это и было сделано. Я немного удивлен, теперь, когда я знаю, в чем проблема, что он не сработал, как только он вступил в _woohoo_, так как ** оригинал ** должен был быть указан до назначения. Хорошо, код работает отлично, если я говорю python, что ** newpic ** является глобальным. Спасибо за вашу помощь :) – tyotypic

0

попробовать, как это (возможно, более лениво?):

from Tkinter import * 
from PIL import Image, ImageTk 

def woohoo(event): 
    global picture # 
    original.putpixel((event.x,event.y),(0,0,255)) 

    picture = ImageTk.PhotoImage(original)# 

    c.itemconfigure(myimg, image=picture)# 


main = Tk() 
c = Canvas(main, width=300, height=300) 
main.geometry("300x300+0+0") 
c.pack() 

original = Image.open("asc.bmp") 
picture = ImageTk.PhotoImage(original) 
myimg = c.create_image((0,0),image=picture, anchor="nw")# 

c.bind("<Button-1>", woohoo) 

main.mainloop() 
+4

Это поможет добавить немного слов, объясняющих, что вы изменили. Просто копирование и вставка кода не поможет никому учиться. –

0

Изменил немного другой должности работать с Python 3+:

from tkinter import * 
 

 
def stuff(event): 
 
    global picture3 
 
    picture3 = PhotoImage(file='picture2.png') 
 
    c.itemconfigure(picture2, image = picture3) 
 

 
main = Tk() 
 
c = Canvas(main, width=300, height=300) 
 
c.pack() 
 

 
picture = PhotoImage(file='picture1.png') 
 
picture2 = c.create_image(150,150,image=picture) 
 

 
c.bind("<Button-1>", stuff) 
 

 
main.mainloop()

Смежные вопросы