1

私の質問はこれに似ています:PythonTKinter複数の操作。ただし、提供された回答は、使用可能な関数のリストが記載された記事を指しているため、役に立ちません。ソリューションの実際の実装を見たいのですが。

私の質問:フレームに2つのボタンがあります。トグル変数がtrueに設定されている限り、1つのボタンで「実行」関数が呼び出されます。2番目のボタンは、トグル値をFalseに設定します。実行ボタンを押すと「実行」機能を継続したいのですが、2番目の(falseを切り替える)ボタンを押すと停止します。ただし、「実行」を押すとフレームが動かなくなります。コールバックのせいでわかりました。どうすればこれを修正できますか?これが私のサンプルコードです:

from Tkinter import *
from time import sleep

class App:

    def __init__(self, master):

        self.toggle = False
        frame = Frame(master)
        frame.pack()

        self.exeButton = Button(frame, text="Execute", fg="blue", command=self.execute)
        self.exeButton.pack(side=LEFT)

        self.tOffButton = Button(frame, text="Toggle Off", command=self.toggleOff)
        self.tOffButton.pack(side=LEFT)

    def execute(self):
        self.toggle = True
        while(self.toggle):
            print "hi there, everyone!"
            sleep(2)

    def toggleOff(self):
    self.toggle = False

root = Tk()
app = App(root)
root.mainloop()
4

1 に答える 1

4

簡単に言えば、あなたはあなたが望むことを正確に行うことはできません。Tkinterはシングルスレッドです-あなたがそれを呼び出すとき、sleep(2)それはあなたがそれを求めることを正確に行います:それは眠ります。

ブールフラグがTrueに設定されている限り、2秒ごとに何かを実行することが目標である場合は、afterを使用して、将来実行するジョブをスケジュールできます。そのジョブがafterを使用してそれ自体を(再)スケジュールする場合、実際のループメカニズムがイベントループ自体である無限ループを効果的に作成したことになります。

私はあなたのコードを取り、フラグが停止するように指示するまで何かを継続的に実行する方法を示すためにいくつかのわずかな変更を加えました。少しわかりやすくするために、「toggle」から「running」に名前を変更する自由を取りました。また、実行をオンまたはオフにするために1つのメソッドのみを使用します。

from Tkinter import *
from time import sleep

class App:

    def __init__(self, master):

        self.master = master
        self.running = False
        frame = Frame(master)
        frame.pack()

        self.exeButton = Button(frame, text="Execute", fg="blue", 
            command=lambda: self.execute(True))
        self.exeButton.pack(side=LEFT)

        self.tOffButton = Button(frame, text="Toggle Off", 
            command=lambda: self.execute(False))
        self.tOffButton.pack(side=LEFT)

    def execute(self, running=None):
        if running is not None:
            self.running = running
        if self.running:
            print "hi there, everyone!"
            self.master.after(2000, self.execute)

root = Tk()
app = App(root)
root.mainloop()
于 2012-08-23T17:31:17.990 に答える