9

私は Tkinter を初めて使用するので、これが簡単な場合は申し訳ありませんが、数時間検索してもわかりません。私がやりたいことは、メインループがアイドル状態になった後、常に関数 checkForGroupUpdates() を呼び出したいということです。以下のコードを実行すると、一度だけ実行されます。メインループがアイドル状態になるたびに実行することがわかりません。助けてくれてありがとう。

from Tkinter import *
import random

class Network(Frame):  
    """ Implements a stop watch frame widget. """                                                               
    def __init__(self, parent=None, **kw):      
        Frame.__init__(self, parent, kw)
        self.makeWidgets()    

    def makeWidgets(self):                       
        """ Make the time label. """
        self._canvas = Canvas(self, width=600, height=400)
        self._canvas.pack()

    def checkForGroupUpdates(self):
        print "checking"
        h=0
        this=10
        while this>.0001:
            this=random.random()
            print h
            h=h+1
        print "checked"


def main():
    root = Tk()
    nw = Network(root)
    nw.pack(side=TOP)

    root.after_idle(nw.checkForGroupUpdates)
    root.mainloop()


if __name__ == '__main__':
    main()
4

2 に答える 2

13

@ user1763510、Bryan Oakley の回答で、彼が再びcheckForGroupUpdates電話をかけたことに注意してください。self.afterこれは、呼び出しが 1 回しかないためです。呼び出しself.afterを繰り返すには、最初の呼び出しで呼び出される関数内で自分自身を呼び出す必要があります。このようにして、繰り返し自分自身を呼び出し続けます。

機能についても同様after_idle()です。checkForGroupUpdates一番下でもう一度電話する必要がありますafter_idle()

after、などのドキュメントは次のとおりです。説明にafter_idleは少しの例もあり、afterすべてが明確になっています。

ドキュメント: http://effbot.org/tkinterbook/widget.htm

上記のリンクの例、after説明の下:

#Method 1
class App:
    def __init__(self, master):
        self.master = master
        self.poll() # start polling

    def poll(self):
        ... do something ...
        self.master.after(100, self.poll)

代わりに使用するafter_idleには、次のようになります。

#Method 2
class App:
    def __init__(self, master):
        self.master = master
        self.poll() # start polling

    def poll(self):
        ... do something ...
        self.master.update_idletasks()
        self.master.after_idle(self.poll)

行の追加に注意してくださいself.master.update_idletasks()。これは GUI を描画し、ボタンの押下などを処理します。そうafter_idle()しないと、すべてのリソースが消費され、GUI が で適切に自己更新されなくなりmainloop()ます。

使用する代わりに

        self.master.update_idletasks()
        self.master.after_idle(self.poll)

使用することです:

        #Method 3
        self.master.update_idletasks()
        self.master.after(0, self.poll)

self.poll を常に実行する必要がないと判断した場合に、0 を別のものに簡単に変更できるため、使用self.master.after(0, self.poll)は私の好みの手法です。遅延時間を少なくとも 1 ミリ秒に増やすことで、呼び出す必要がまったくなくなりますself.master.update_idletasks()。したがって、これも機能します。

        #Method 4
        self.master.after(1, self.poll)

また、上記のすべての例self.poll()では、関数の呼び出しがすべての開始点であり、たとえばを介して内部でまたは関数を呼び出すことができるようにするために、単にへ__init__の格納が必要であることに注意してください。masterself.masterpollafterafter_idleself.master.after_idle

Q: これは安定して動作しますか?
A: 上記の方法 3 を使用してテスト コードを約 21 時間実行しましたが、その間ずっと安定して実行され、GUI を使用できるようになりました。

Q: 上記の各方法の速度比較は?
A:

  • 方法 1: (速度テストはしていません)
  • 方法 2: ~0.44 ミリ秒/反復
  • 方法 3: ~0.44 ミリ秒/反復
  • 方法 4: ~1.61 ミリ秒/反復

Q: 私の好みの方法はどれですか?
A: 方法 3 または 4 です。

于 2016-08-07T18:55:32.167 に答える