简体   繁体   English

需要Python TKinter线程帮助

[英]Python TKinter Threading Help Required

I am trying to create a GUI that communicates with a RS232 serial object. 我正在尝试创建一个与RS232串行对象通信的GUI。 I'll present an analogous scenario to the problem that I am facing. 我将针对所面临的问题提出一个类似的场景。 I want to create a frame with 2 buttons, Start and Stop. 我想用2个按钮(开始和停止)创建框架。 The start button calls the 'foo' function: 开始按钮调用“ foo”函数:

status = True

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

This foo function keeps running until I press stop. 直到我按停止,该foo函数一直运行。

def getStatus():
   return status

def stop():
   status = False

I understand Tkinter is single-threaded and once I press 'Start', the GUI will freeze. 我了解Tkinter是单线程的,一旦按下“开始”,GUI将冻结。 I know this is possible with the after function, but i strictly want to use threading . 我知道这可以通过after函数实现,但是我严格地希望使用threading Is this possible with threading? 使用线程有可能吗? If so can you please provide a sample code? 如果可以,请提供示例代码? Thank you. 谢谢。

here is some (not yet perfect) code: 这是一些(尚未完善)的代码:

What is missing/broken, but you did not ask for this, I added links: 丢失/损坏了什么,但您没有要求这样做,我添加了链接:

  • It does not use locks => the calls to set might brake since they can occur at the same time. 它不使用锁=> set的调用可能会制动,因为它们可能同时发生。 read the docs (this is quite easy) 阅读文档 (这很容易)
  • It updates the gui from another thread. 它从另一个线程更新gui。 see 1 2 1 2
  • possibly more (not a threading guru) 可能更多(不是线程大师)

Also for stopping threads look here 也可以在这里停止线程

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM