【问题标题】:Python Tkinter While ThreadPython Tkinter While 线程
【发布时间】:2016-09-25 17:52:11
【问题描述】:

好吧,我在 python 方面有点新手,我越来越难以在 Tkinter 中创建一个线程,正如你们都知道的那样,在 Tkinter 中使用 while 会使其无响应并且脚本仍在运行。

  def scheduler():
    def wait():
        schedule.run_pending()
        time.sleep(1)
        return
    Hours = ScheduleTest()
    if len(Hours) == 0:
        print("You need to write Hours, Example: 13:30,20:07")
    if len(Hours) > 0:
        print("Scheduled: ", str(Hours))
        if len(Hours) == 1:
            schedule.every().day.at(Hours[0]).do(Jumper)
            print("Will jump 1 time")
        elif len(Hours) == 2:
            schedule.every().day.at(Hours[0]).do(Jumper)
            schedule.every().day.at(Hours[1]).do(Jumper)
            print("Will jump 2 times")
        elif len(Hours) == 3:
            schedule.every().day.at(Hours[0]).do(Jumper)
            schedule.every().day.at(Hours[1]).do(Jumper)
            schedule.every().day.at(Hours[2]).do(Jumper)
            print("Will jump 3 times")
        while True:
            t = threading.Thread(target=wait)
            t.start()
    return
scheduler()

我试图做这样的事情,但它仍然让 tkinter 没有响应 提前致谢。

【问题讨论】:

  • 只需使用 after() stackoverflow.com/a/39632315/1391444 一个或多个循环同样有效。
  • 你的意思是在睡眠后使用?像 root.after(10000) 而不是时间,睡觉?我试过这样做,但它没有用,要么我不明白该放在哪里,要么它对我不起作用
  • 我必须跑,但如果你不跑,我会回来的。
  • @JacobVlijm 我没搞定,你还能帮我吗?
  • 好的,我会在几个小时内发布答案。

标签: python multithreading tkinter python-multithreading schedule


【解决方案1】:

什么时候使用after方法;在没有线程的情况下伪装

正如评论中提到的,在大多数情况下,您不需要线程来运行“假”while 循环。您可以使用after() 方法来安排您的操作,使用tkinter 的mainloop 作为“衣帽架”来安排事情,就像您在while 循环中所做的一样。

这适用于您可以简单地抛出命令的所有情况,例如subprocess.Popen(),更新小部件,显示消息等

当计划的进程花费大量时间时,它确实不工作,在主循环中运行内部。因此time.sleep() 是一个无赖;它只会保存mainloop。

工作原理

但是,在该限制内,您可以运行复杂的任务、安排操作甚至设置break(-等价)条件。

只需创建一个函数,使用window.after(0, <function>) 启动它。在函数内部,(重新)使用window.after(<time_in_milliseconds>, <function>) 调度函数。

要应用类似中断的条件,只需将进程(函数内部)路由到不再被调度。

一个例子

最好用一个简化的例子来说明这一点:

from tkinter import *
import time

class TestWhile:
    
    def __init__(self):
        
        self.window = Tk()
        shape = Canvas(width=200, height=0).grid(column=0, row=0)
        self.showtext = Label(text="Wait and see...")
        self.showtext.grid(column=0, row=1)
        fakebutton = Button(
            text="Useless button"
            )
        fakebutton.grid(column=0, row=2)
        
        # initiate fake while
        self.window.after(0, self.fakewhile)
        self.cycles = 0
       
        self.window.minsize(width=200, height=50)
        self.window.title("Test 123(4)")
        self.window.mainloop()

    def fakewhile(self):
        # You can schedule anything in here
        if self.cycles == 5:
            self.showtext.configure(text="Five seconds passed")
        elif self.cycles == 10:
            self.showtext.configure(text="Ten seconds passed...")
        elif self.cycles == 15:
            self.showtext.configure(text="I quit...")
        """
        If the fake while loop should only run a limited number of times,
        add a counter
        """
        self.cycles = self.cycles+1
        """
        Since we do not use while, break will not work, but simply
        "routing" the loop to not being scheduled is equivalent to "break":
        """
        if self.cycles <= 15:
            self.window.after(1000, self.fakewhile)
        else:
            # start over again
            self.cycles = 0
            self.window.after(1000, self.fakewhile)
            # or: fakebreak, in that case, uncomment below and comment out the
            # two lines above
            # pass

TestWhile()

在上面的示例中,我们运行了一个预定进程十五秒。在循环运行时,函数fakewhile() 会及时执行几个简单的任务。

在这十五秒之后,我们可以重新开始或“休息”。只需取消注释指示的部分即可查看...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多