0

私はTkに比較的不慣れですが、以前にいくつかの簡単なプロジェクトを行ったことがあり、これは私を困惑させました:

タイムスライダーを表すスケールウィジェットがあります。threading.Timerは、スケールウィジェットを移動するために間隔を置いてオフになります。ボタンを押すと、スレッドは無効になります。ボタンを押すと、スレッドが再び有効になります。そのため、ユーザーはタイムスライダーをクリックしてドラッグし、アプリケーションの「時間」の位置を変更できます。UI操作中にスレッドを無効にすることで、これまでのところ、スレッドの安全性に関連していると思われるクラッシュを防ぐことができました(スレッドがスライダーを更新しようとしたときに発生した、非決定的なクラッシュのようです)。

他の唯一の「アクティブな」UI要素は、command=fncパラメーターを使用して構成された一連のボタンです。スケールは私がbind()を使用している唯一の場所です。このアプリケーションはフルスクリーンアプリなので、ルートレベルでself.root.overridedirect(1)とgeometry()を使用して、メニューと境界線を削除し、フルスクリーンにします。

コードを変更したので、スケールウィジェットは絶対ルートレベルではなくフレーム内にあります。

self.scale_timescrub = tkinter.Scale(self.root.master, from_=0, to=60, width=height_one, orient=tkinter.HORIZONTAL, showvalue=0)
self.scale_timescrub.grid(row=2,column=0,sticky=tkinter.N+tkinter.S+tkinter.E+tkinter.W)
self.scale_timescrub.bind('<Button-1>', self.press_scrub)
self.scale_timescrub.bind('<ButtonRelease-1>', self.release_scrub)

これで、スケールウィジェットを使用してUI操作を実行しようとすると、アプリケーションがハングします。スライダーのどこかを押すとCPUが固定され、アプリが元に戻ることはありません。アプリケーションをハックしてスケールをルートレベルに戻すと、再び機能するため、子育てに関連していることはわかっています。ウィジェットは、フレームにペアレント化されている場合、press_scrubなどのバインドされた関数に入ることがないようです。

誰かが私がここで間違っていることを私にアドバイスできますか?

Windows7でpython3.2.364bを実行します。

4

2 に答える 2

0

問題は、フルウィンドウのFrameオブジェクトの名前として「master」キーワードを使用していることにあるようです。self.root.masterの名前をself.root.full_frameに一括変更すると、すべてが期待どおりに機能します。スレッドの危険性を指摘してくれたBryanに感謝します。これを使用して、アプリケーションの他の側面を再評価します。再現可能なものに関心を示してくれたmgilsonに感謝します。非常に多くの奇妙な構成が設定されているので、それらのいずれかが関係している可能性があると思ったので、投稿する前に再現可能なものをペアリングしていませんでした。とにかく、みんなに感謝します。自己への注意:何も「マスター」と呼ばないでください。

于 2012-05-21T19:55:18.427 に答える
0

あなたは次のように書いています:「スレッド。タイマーは、スケールウィジェットを動かすために間隔を置いてオフになります」。このタイマーイベントを処理する際に、別のスレッドからウィジェットメソッドを呼び出していますか?もしそうなら、それは間違いなく問題です。UIを別のスレッドから変更することはできません。

Timerオブジェクトは必要ありません-を使用して定期的に実行するように何かをスケジュールできることを知っていますafterか?

考慮すべきもう1つのことは、コードスニペットを見ても判断できないことですpackが、同じコンテナーウィジェットで使用しているかどうかです。同じマスターで組み合わせるpackgrid、表示される動作が発生します。通常、このような場合、起動時にその動作が見られますが、常にそうとは限りません。

于 2012-05-21T11:10:53.013 に答える