0

I've a tkinter application running the main thread and a second thread that captures images from the PiCamera of my raspberry pi and updating the canvas in the main window. When I stop my application (using a close button), I update an attribute of my thread class to stop the thread, then wait for the thread to join and quit the app. I use the following code to update the image to my canvas :

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)

The problem is when I stop my thread, I'm blocked to joining method and my thread won't stop. After some tests, I found out it was "photo=ImageTk.PhotoImage(image=im)" that was blocking my program. If I close the program using the X button, the for loop keeps running writting on output :

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

Does anybody know why this line won't let my thread stop?

Here is a short extract of my program :

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()
Fosheus Badabu
  • 351
  • 1
  • 3
  • 10
  • You have a method called `stop` which is overwritten in the `__init__()` method by a boolean value `False`, so you should get an exception when you try to call the `bool` instance. – BlackJack May 03 '17 at 15:53
  • @BlackJack Thank you for your response but i changed my mind, it is not verry efficient to use a canvas and updated it regulary. Sometime it displays a blank image during some fraction of second. I now display a window with opencv imshow method next to my application. It does the same though the window and application are not connected. – Fosheus Badabu May 04 '17 at 14:21

0 Answers0