私はtkinterを使用してGUIにダイヤルアップしています。アプリケーションが終了したときにスレッドをすべてクリーンアップして責任ある市民になろうとしています。私のアプリケーションはマルチスレッドで、ポーリングエンジンは定期的にアップデートをディスプレイに送り返します。私は共有リソースへのアクセスを制御するためにリソースロックを使用しています(下のサンプルコードには示されていません)。問題は、非常に頻繁にアプリケーションウィンドウを閉じた後、残っているスレッドに悩まされていることです。tkinter(python GUI)ウィジェットが無効になるまでの呼び出し
私は以下のコードで私が作業していることを示してみました: "更新"のコールバックは非同期です。問題は、基礎となるウィジェットのステータスを「self._active」にチェックしてから、「... frameWidget.configure(style = ...」および「...」を呼び出した時刻varToUpdate.set(... ")これらのウィジェットの状態は、tkinterエンジンによって「無効」/「応答なし」という風味に変更されている可能性があります。
ロックを使用するとヘルプが表示されません。ウィジェットの状態を制御して、私が物事をきれいにするまで瀕死状態にならないようにしますイベント通知は単にイベントが発生したと伝えますが、
本当の問題は、ウィジェットのスタイルを設定するための呼び出し( "self.frameWidget.configure( GUIがシャットダウンされたときに単にハング/ブロックするだけで、IntVar( "self.varToUpdate.set(value)")を更新することができます。
例外を生成するのではなく、何も返さない場合、これらのメソッド呼び出しは返されません。 (これは私にとっては良い行動ではないようです。)
So.これに対処する方法は?何か案は?私は本当に "原子"としてのコードのチャンクを何とか指定することが大好きです。オブジェクト操作が "._active"のチェックの直後に実行されることが保証されていましたが、Pythonのようなものは見たことがありません。私がそれを達成することができたとしても、tkinkerエンジンが実際にオブジェクトを更新する方法がわからないので、問題を解決できない可能性があります。何か不足していますか?
はい、私はPython、bla bla blaを初めて使っています...私はJavaの背景から来ているので、私が書いたことの多くは確かに "非python"であると仮定します。私は言語の強みを活かすために、ここでどのように改善するかもしれないかについてのあなたの洞察を聞いて本当にうれしく思います。
サンプルコード!
デーモンが「T」は、メインスレッドがを終了したとき、私はまだTkinterの方法は、ブロッキング/ハングによって不完全に振る舞うことを感じて終わるだけで結構
t = Thread(target=self.pollData)
t.daemon = True
t.start()
スレッドを働いたとして、バックグラウンドスレッドを設定
from tkinter import *
from tkinter import ttk
from myutil import Subscriber
threshold = 20
deactivationEvents = ("Deactivate", "Destroy", "Unmap")
activationEvents = ("Activate", "Map")
# class implements/inherits "listener pattern" functionality
class MyClass(Subscriber)
def __init__(self, parentWidget):
self._active = False
self.frame = ttk.LabelFrame(parentWidget, text='something')
self.varToUpdate = IntVar()
self.bar = ttk.Progressbar(self.frame, orient=VERTICAL)
self.bar.config(mode='determinate', maximum=100, variable=self.varToUpdate)
self.moreThings()
self.bindWidgetEvents():
. more
. code
. here
# I'm using a simple boolean flag to control access here
# I've tried using threading.Lock as well, to no avail
def update(self, value):
stylename = "{}.TFrame".format("Normal" if value > threshold else "Alarm")
if self._active:
self.frame.configure(style=stylename)
self.varToUpdate.set(value)
def bindWidgetEvents(self):
widgets = [self.bar, self.frame]
self.bindActivationEvents(widgets)
self.bindDeactivationEvents(widgets)
def bindActivationEvents(self, widgets):
def activate(event):
self._active = True
for widget in widgets:
for event in activationEvents:
widget.bind("<{}>".format(event), activate)
def bindDeactivationEvents(self, widgets):
def deactivate(event):
self._active = False
for widget in widgets:
for event in deactivationEvents:
widget.bind("<{}>".format(event), deactivate)
スレッドスレッドのデーモンを親スレッドで終了させるだけです。 – Novel
まあ、それは確かに働いた!私はまだ、それらの方法は、彼らが行う方法をぶら下げるよりも例外を提起する必要があるように感じる...ありがとうございます! –