2016-05-02 11 views
0

私はtkinterで単純なウィンドウを作成し、それをスレッドとして起動してメインプログラムをウィンドウの隣で実行し続けます。Python:スレッドが所有する変数にアクセスしようとすると、属性エラーが発生する

AttributeError: 'mainWindow' object has no attribute 'w' 

なぜことができます:私は示されているコードウィンドウが正常に開きますが、私はmove_brick(...)で四角形を移動しようとすると、私はこのエラーを取得を実行すると

import tkinter as tk 
import threading 

class mainWindow(threading.Thread): 
    def __init__(self, winWidth=500, winHeight=300): 
     threading.Thread.__init__(self) 
     self.winWidth = winWidth 
     self.winHeight = winHeight 

     # Save all drawn objects, to move or delete them later 
     self.bricks = [] 

     self.start()     #start thread 

    def run(self): 
     # parent object for all windows 
     self.master = tk.Tk() 
     self.master.protocol("WM_DELETE_WINDOW", self.callback) 
     self.show() 

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

    # Initialize everything important 
    def show(self, tileSize=10): 
     # create main window 
     self.w = tk.Canvas(
       self.master, 
       width=self.winWidth, 
       height=self.winHeight, 
       background="white") 

     self.w.pack() 

     # draw brick 
     color = "gray49" 
     posX = 200 
     posY = 100 
     self.bricks.append(self.w.create_rectangle(posX, posY, posX+20, posY+20, fill=color)) 
     tk.mainloop() 

    def move_brick(self, x,y): 
     self.w.move(self.brick, x, y) 


mainWindow = mainWindow() 
mainWindow.move_brick(100,100) 

:これはそれの短縮バージョンですオブジェクトが私のCanvas wを見つけるのですか?

答えて

1

おそらくスレッド化されたアプリケーションで一般的な競合状態があります。主スレッドは、ワーカースレッドがウィジェットを作成する前にmove_brickを呼び出す可能性があります。

ウィジェットを作成する前後にprintステートメントを追加した場合や、move_brick関数でこの問題が発生している可能性があります。

これを修正しても、すべてのtkinterコードが1つのスレッドで実行される必要があるため、このコードは機能しません。あるスレッドでGUIを作成し、別のスレッドでmove_brickを呼び出すことは、tkinterを使用する正しい方法ではありません。

+0

私はtkinterを初めて使用しており、いくつかのプロセスをデバッグするためにのみ使用します。メインプログラムからGUIを変更するにはどうしたらいいですか? – Jonas

+0

print文で確認しましたが、ウィンドウの初期化後に 'move_brick()'を十分に遅く呼び出すとうまく動作します。 – Jonas

+0

@Jonas:re _ "GUIを変更するにはどのようにすればいいですか?"はあなたが実際にやろうとしていることに依存します。もしあなたがしていることが動いているなら、あなたの周りの数百のレンガはスレッドを必要としません。 Tkinterには、アイテムを画面上で動かすなど、定期的に実行するためのメソッド( 'after')があります。 –

関連する問題