2016-06-21 9 views
0

私は別のStackoverflow質問の解決に基づいて、次のスクリプトを持っています。私は新しいものを取ったときに更新する必要がある画像とGUIのGUIを持っています。GPIOボタンを押した後、Tkinterで画像をリロードする方法はありますか?

class App(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
     self.start() 

    def callback(self): 
     self.root.quit() 

    def run(self): 
     self.root = Tk() 
     self.root.geometry("{0}x{1}+0+0".format(800,800)) 

     files = sorted(os.listdir(os.getcwd()),key=os.path.getmtime) 

     Label(self.root,image = ImageTk.PhotoImage(Image.open(files[-1]).resize((300, 200)))).grid(row = 1, column = 0) 

     Label(self.root, text=files[-1]).grid(row=0, column=0) 
     self.root.mainloop() 

    def update(self): 

     files = sorted(os.listdir(os.getcwd()),key=os.path.getmtime) 

     img1 = self.ImageTk.PhotoImage(self.Image.open(files[-1]).resize((300, 200))) 
     Label(self.root,image = img1).grid(row = 1, column = 0) 

     Label(self.root, text=files[-1]).grid(row=0, column=0) 

     self.root.update() 

app = App()   
app.update() 

私はこのエラーを取得する:

Traceback (most recent call last): 
    File "/usr/lib/python3/dist-packages/PIL/ImageTk.py", line 176, in paste 
    tk.call("PyImagingPhoto", self.__photo, block.id) 
_tkinter.TclError: invalid command name "PyImagingPhoto" 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "./mainloop.py", line 98, in <module> 
    app.update() 
    File "./mainloop.py", line 79, in update 
    img1 = ImageTk.PhotoImage(Image.open(files[-1]).resize((300, 200))) 
    File "/usr/lib/python3/dist-packages/PIL/ImageTk.py", line 115, in __init__ 
    self.paste(image) 
    File "/usr/lib/python3/dist-packages/PIL/ImageTk.py", line 182, in paste 
    _imagingtk.tkinit(tk.interpaddr(), 1) 
OverflowError: Python int too large to convert to C ssize_t 

は私が間違って何をしているのですか?ファイル名でラベルを作成すると機能します。ファイル名は有効なファイルです。スクリプトはthread.Threadingの内部にないときに機能します。ラズベリーのGPIOボタンが押されたときに最新の画像で画面を更新したいと思います(スクリプトはカマラで新しい写真を撮ります)。したがって、画面には最新の撮影画像がロードされます。

答えて

0

tkinterはではなく、スレッドセーフ(デフォルト)です。 GUIを扱うすべての操作は、メインスレッドで行わなければなりません。イベントのコールバックを使って何を求めているのかは分かりますが、メインループに入るイベントキューを実装していない限り、スレッド化はできますし、tkinterを破ります。

さらに、スタックトレースは、ここではコードではなく、スタックトレースが提示されたコードとまったく交差していないように見えます。

また、root.update()を呼び出すことは、一般的には別のローカルイベントループを開始し、別のイベントループad infiniumに対して別のroot.update()を呼び出すことができる可能性があります。 root.update_idletasks()は完全なroot.update()よりもはるかに安全です

関連する問題