1

RS232 シリアル オブジェクトと通信する GUI を作成しようとしています。私が直面している問題に類似したシナリオを提示します。Start と Stop の 2 つのボタンがあるフレームを作成したいと考えています。スタート ボタンは「foo」関数を呼び出します。

status = True

def foo():
   n = 0
   while(getStatus()):
       print n
       n += 1
       sleep(0)

この foo 関数は、停止を押すまで実行を続けます。

def getStatus():
   return status

def stop():
   status = False

Tkinter がシングル スレッドであることを理解しています。[開始] を押すと、GUI がフリーズします。after関数でこれが可能であることは知っていますが、厳密にはthreadingを使用したいと考えています。これはスレッド化で可能ですか?もしそうなら、サンプルコードを提供してもらえますか? ありがとうございました。

4

1 に答える 1

1

ここにいくつかの(まだ完全ではない)コードがあります:

不足している/壊れているものはありますが、あなたはこれを求めていませんでした。リンクを追加しました:

  • ロックを使用しません => set の呼び出しは同時に発生する可能性があるため、ブレーキがかかる可能性があります。ドキュメントを読む(これはとても簡単です)
  • 別のスレッドから gui を更新します。1 2を参照
  • おそらくそれ以上(スレッドの第一人者ではありません)

また、スレッドを停止するには、こちらをご覧ください

import time
import tkinter
from tkinter import ttk
import threading  

#gui
root = tkinter.Tk()
root.title("Threading demo")

status = tkinter.StringVar()
elapsed = tkinter.StringVar()
error = tkinter.StringVar()

#thread
class timer(threading.Thread):
    def __init__(self):
        super().__init__()
        self.stopped = False
        #your code here, don't need init if you have no code



    def run(self):
        status.set('running')

        while not self.isStopped():
            time.sleep(1)

            try:
                oldtime = int(elapsed.get())
            except ValueError:
                oldtime = 0

            elapsed.set(oldtime+1)

        status.set('stopped')
        time.sleep(2)

    def isStopped(self):
        return self.stopped



    def stop(self):
        self.stopped = True



#starts/stops thread (manages it)
class threadedOp(object):
    def __init__(self):
        self.thread = None


    def run(self):
        if self.thread == None:
            self.thread = timer()
            status.set('starting')
            self.thread.start()
        else:
            error.set('Thread already running')


    def stop(self):
        if self.thread != None:
            status.set('stopping')
            self.thread.stop()
            self.thread.join()
            error.set('Join complete')
            self.thread = None
        else:
            error.set('No thread to stop')

op = threadedOp()

#remaining gui
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(tkinter.N, tkinter.W, tkinter.E, tkinter.S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

ttk.Label(mainframe, textvariable=elapsed).grid(column=1, row=1, sticky=(tkinter.W, tkinter.E))
ttk.Label(mainframe, textvariable=status).grid(column=2, row=1, sticky=(tkinter.W, tkinter.E))
ttk.Label(mainframe, textvariable=error).grid(column=1, row=3, sticky=(tkinter.W, tkinter.E))
ttk.Button(mainframe, text="Start", command=op.run).grid(column=1, row=2, sticky=tkinter.W)
ttk.Button(mainframe, text="Stop", command=op.stop).grid(column=2, row=2, sticky=tkinter.W)

root.mainloop()
于 2012-08-29T08:50:00.520 に答える