python脚本在x秒后运行,但是当插入tkinter代码时,它仅运行一次

时间:2019-03-21 06:21:26

标签: python tkinter

What is the best way to repeatedly execute a function every x seconds in Python?

我尝试了以上链接上发布的解决方案,但没有一个能帮助我达到预期的结果。

上面的代码按每秒提及的秒数在控制台上多次打印“正在执行...”,即5,但是当我添加window()行(这是显示消息的tkinter代码)时,该代码仅运行一次,而不是再来一次。

请帮助。我想按照系统时钟在特定时间一次又一次地运行tkinter代码,但是现在我只是想在x秒后执行它。

任何帮助对我来说真的很重要。谢谢

2 个答案:

答案 0 :(得分:1)

搜索tkinter .after方法。

这将使您每x秒运行一次命令。

您的tkinter代码仅运行一次的问题是,因为它首先被设置,然后进入循环(root.mainloop()),因此再也不会返回您的代码来再次显示任何内容。

示例:ValueTuple

答案 1 :(得分:0)

我认为您需要线程和队列...让我展示一些演示。

我在thead类中设置了time.sleep(1)每秒。

在这种情况下,您有两个好处,首先是随时重复使用功能

您渴望并且第二次您的程序永远不会冻结自己。

import tkinter as tk
import threading
import queue
import datetime
import time

class MyThread(threading.Thread):

    def __init__(self, queue,):
        threading.Thread.__init__(self)

        self.queue = queue
        self.check = True

    def stop(self):
        self.check = False

    def run(self):


        while self.check:
            x = "Doing stuff.. "
            y = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            msg = x+y
            time.sleep(1)
            self.queue.put(msg)


class App(tk.Frame):

    def __init__(self,):

        super().__init__()

        self.master.title("Hello World")
        self.master.protocol("WM_DELETE_WINDOW",self.on_close)

        self.queue = queue.Queue()

        self.my_thread = None

        self.init_ui()

    def init_ui(self):

        self.f = tk.Frame()

        w = tk.Frame()

        tk.Button(w, text="Start", command=self.launch_thread).pack()
        tk.Button(w, text="Stop", command=self.stop_thread).pack()
        tk.Button(w, text="Close", command=self.on_close).pack()

        w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=0)
        self.f.pack(side=tk.LEFT, fill=tk.BOTH, expand=0)

    def launch_thread(self):

        if (threading.active_count()!=0):

            self.my_thread = MyThread(self.queue)
            self.my_thread.start()
            self.periodiccall()

    def stop_thread(self):

     if(threading.active_count()!=1):
         self.my_thread.stop()


    def periodiccall(self):

        self.checkqueue()
        if self.my_thread.is_alive():
            self.after(1, self.periodiccall)
        else:
            pass

    def checkqueue(self):
        while self.queue.qsize():
            try:
                ret = self.queue.get(0)
                msg = "%s"%(ret)
                print(msg)
            except queue.Empty:
                pass                    

    def on_close(self):
        if(threading.active_count()!=1):
            self.my_thread.stop()

        self.master.destroy()

if __name__ == '__main__':
    app = App()
    app.mainloop()