У меня есть приложение tkinter, в котором работает основной поток и второй поток, который захватывает изображения с PiCamera моего Raspberry Pi и обновляет холст в главном окне. Когда я останавливаю свое приложение (используя кнопку закрытия), я обновляю атрибут своего класса потока, чтобы остановить поток, затем жду, пока поток присоединится, и выйду из приложения. Я использую следующий код для обновления изображения на моем холсте:
im=Image.fromarray(image)
photo=ImageTk.PhotoImage(image=im)
for item in self.window.canvas.find_all():
self.window.canvas.delete(item)
self.window.canvas.create_image(0,0,anchor=NW,image=photo)
Проблема в том, что когда я останавливаю свой поток, я блокирую метод присоединения, и мой поток не останавливается. После некоторых тестов я обнаружил, что "photo=ImageTk.PhotoImage(image=im)" блокирует мою программу. Если я закрываю программу с помощью кнопки X, цикл for продолжает работать, записывая на выходе:
Exception AttributeError: "PhotoImage instance has no attribute
'_PhotoImage__photo'" in <bound method PhotoImage.__del__ of
<PIL.ImageTk.PhotoImage instance at 0x76a2fbe8>> ignored
Too early to create image
Кто-нибудь знает, почему эта строка не позволяет моему потоку остановиться?
Вот краткий отрывок из моей программы:
import *
class Worker(Thread):
def __init__(self, window):
Thread.__init__(self):
self.window = window
self.stop=False
def run(self):
#init camera
...
#capture loop
while(self.stop==False):
for frame in cam.capture_continuous(...)
image= frame.array
im=Image.fromarray(image)
photo=ImageTk.PhotoImage(image=im)
for item in self.window.canvas.find_all():
self.window.canvas.delete(item)
self.window.canvas.create_image(0,0,anchor=NW,image=photo)
if self.stop ==True:
break
def stop(self):
self.stop=True
class Window(Tk):
def __init__(self):
Tk.__init__(self)
self.thread=Worker(self)
self.btnQuit=Button(self,text="Quit",command=self.closeApp)
self.canvas = Canvas(self,width=1280,height=720,bg='white')
self.canvas.grid(row=1)
self.btnQuit.grid(row=1,column=2)
self.thread.start()
def closeApp(self):
self.thread.stop()
self.thread.join()
self.quit()
stop
, который перезаписывается в методе__init__()
логическим значениемFalse
, поэтому вы должны получить исключение при попытке вызвать экземплярbool
. - person BlackJack   schedule 03.05.2017