マルチスレッドとtkinterで苦労しています。slxl私が使用するモジュールは動作し、その関数は値を返しません (混乱がないことを確認するためだけです)。
過去に機能したコードは次のとおりです。
#relevant tkinter code
def create_widgets():
self.updatebttn = Button(self, text='Auto Update', command=self.spawnthread)
self.updatebttn.grid(row=1, column=0, sticky=N)
self.progressbar = Progressbar(self, orient='horizontal',
length=300, mode='determinate')
self.progressbar.grid(row=1, column=1, sticky=W)
self.progressbar["maximum"] = (slxl.sizeFinder()) * 1.1
def spawnthread(self):
self.updatebttn.config(state="disabled")
self.thread = ThreadedClient1(self.queue)
self.thread.start()
self.periodiccall()
def periodiccall(self):
if self.thread.is_alive():
self.after(100, self.periodiccall)
self.progressbar.step(500)
else:
self.updatebttn.config(state="active")
self.progressbar.stop()
class ThreadedClient1(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
time.sleep(1)
importer = slxl.runImportAndCoordAdder()
self.queue.put(importer)
問題は、ThreadedClient1 がキューに入れている関数を、この場合slxl.runImportAndCoordAdder()は引数として取得できるようにしたいということです。これはThreadedClient、異なる関数で複数回使用するためです (後でプログラムで同じように使用します)。異なる関数のみ)ThreadedClient1とを持つのは好きではありません。ThreadedClient2唯一の違いはimporter =異なる関数です。
私はそのようなラムダで解決策を試みました:
def spawnthread(self):
self.updatebttn.config(state="disabled")
self.thread = ThreadedClient1(self.queue, lambda: slxl.runImportAndCoordAdder())
self.thread.start()
self.periodiccall()
#periodic call is the same
class ThreadedClient1(threading.Thread):
def __init__(self, queue, fcn):
threading.Thread.__init__(self)
self.queue = queue
self.fcn = fcn
def run(self):
time.sleep(1)
self.queue.put(lambda: self.fcn)
私が興味を持っている機能を無視し、プログレスバーを少し動かしたり無効にしたり、ボタンを有効にしたりして終了したため、これは機能しませんでした。
私は何を間違っていますか?
編集:
問題は解決しました。しかし、別のものが出てきました。spawnthread、periodiccall、およびを私が持っているウィジェット テンプレート モジュールに転送し、ThreadedClientそれらを一般化して簡単に使用できるようにしたいと考えています。これは私がしました:
def spawnthread(self, widget):
widget.config(state="disabled")
self.thread = ThreadedClient1(self.queue)
self.thread.start()
self.periodiccall()
私も一般化しようとするまで、これはperiodiccallうまくいきました。
#...
self.periodiccall(widget=widget)
def periodiccall(self, widget=None):
if self.thread.is_alive():
self.after(100, self.periodiccall)
self.progressbar.step(500)
#print widget
else:
widget.config(state="active")
self.progressbar.stop()
print widget属性エラーが発生し続けたので、何が起こっているのかを確認するためにポップインしました。起こっているように見えるのは、最初に「ウィジェット」が何であるかを知っている関数を実行した後、ステートメントNoneで呼び出して、私が望んでいたものに変わるということです。少なくとも、それが起こっていると思います。このエラーを取り除き、この再帰関数でウィジェットを変数にするにはどうすればよいですか?self.periodiccallafter