如何在python中启动计时器并重置它?

如何在python中启动计时器并重置它?,python,Python,我在类上初始化了一个计时器,在指定的秒后,它将调用另一个目标函数。在加载情况下,它将显示欢迎功能gui并打开串行端口 在通过串行端口接收数据时,我想查询web api上的信息,在显示信息后,我想启动\uuuuu init\uuuuu上声明的计时器 但是,如果在计时器运行之前有另一个数据通过串行端口进入,我希望随着更多数据进入,计时器重新启动/重置,我不必再次显示欢迎功能,直到计时器运行之间没有任何东西进入 我从中发现了一些东西,但它不会触发回调函数 from threading import T

我在类上初始化了一个计时器,在指定的秒后,它将调用另一个目标函数。在加载情况下,它将显示欢迎功能gui并打开串行端口

在通过串行端口接收数据时,我想查询web api上的信息,在显示信息后,我想启动
\uuuuu init\uuuuu
上声明的计时器

但是,如果在计时器运行之前有另一个数据通过串行端口进入,我希望随着更多数据进入,计时器重新启动/重置,我不必再次显示欢迎功能,直到计时器运行之间没有任何东西进入

我从中发现了一些东西,但它不会触发回调函数

from threading import Thread, Timer

class TimerThread(threading.Thread):
    def __init__(self, timeout=3, sleep_chunk=0.25, callback=None, *args):
        threading.Thread.__init__(self)
        print('timer:initialized')
        self.timeout = timeout
        print('timeout:' + str(timeout))
        self.sleep_chunk = sleep_chunk
        print('timeout:' + str(sleep_chunk))
        if callback == None:
            self.callback = None
            print('callback:none')
        else:
            self.callback = callback
            print('callback:' + str(callback))
        self.callback_args = args

        self.terminate_event = threading.Event()
        self.start_event = threading.Event()
        self.reset_event = threading.Event()
        self.count = self.timeout/self.sleep_chunk

    def run(self):
        print('timer:run')
        while not self.terminate_event.is_set():
            while self.count > 0 and self.start_event.is_set():
                if self.reset_event.wait(self.sleep_chunk):  # wait for a small chunk of timeout
                    self.reset_event.clear()
                    self.count = self.timeout/self.sleep_chunk  # reset
                self.count -= 1
            if self.count <= 0:
                self.start_event.clear()
                print('timeout. calling function...')
                self.callback(*self.callback_args)
                self.count = self.timeout/self.sleep_chunk  # reset

    def start_timer(self):
        print('start_timer')
        self.start_event.set()

    def stop_timer(self):
        print('stop_timer')
        self.start_event.clear()
        self.count = self.timeout / self.sleep_chunk  # reset

    def restart_timer(self):
        # reset only if timer is running. otherwise start timer afresh
        print('restart_timer')
        if self.start_event.is_set():
            self.reset_event.set()
            print('restart_timer:reset')
        else:
            self.start_event.set()
            print('restart_timer:start')

    def terminate(self):
        print('terminate')
        self.terminate_event.set()

class Application(Tk):
    def show_idle_screen(self):
        for widget in self.winfo_children():
            widget.destroy()
        # Create new widget element

    def show_product_info(self, barcodeno):
        # call web api and get response
        # create information widget element
        # -Timer(5.0, self.show_idle_screen).start()
        tmr = TimerThread(timeout, sleep_chunk, Application().show_idle_screen)
        tmr.restart_timer()


    def serial_port_data_received(self):
        if self.serial.inWaiting() > 0:
            # The rest of handling serial data
            # UPDATED CODE START
            # -if self.idle_timer.is_alive():
            #     -print('cancelling timer')
            #     -self.idle_timer.cancel()
            # UPDATED CODE END
            self.query_thread = Thread(target=lambda: self.show_product_info(barcodedata))
            self.query_thread.start()


    def __init__(self):
            # Initialization of timer
            # -self.idle_timer = Timer(5.0, self.show_idle_screen)
            self.new_thread = Thread(target=self.show_idle_screen)
            self.new_thread.start()

root = Application()
root.mainloop()

从线程导入线程,计时器
类TimerThread(threading.Thread):
def uuu init uuuu(self,timeout=3,sleep\u chunk=0.25,callback=None,*args):
threading.Thread.\uuuuu init\uuuuuu(自)
打印('计时器:已初始化')
self.timeout=超时
打印('超时:'+str(超时))
self.sleep\u chunk=睡眠块
打印('超时:'+str(睡眠块))
如果回调==无:
self.callback=None
打印('回调:无')
其他:
self.callback=回调
打印('callback:'+str(callback))
self.callback_args=args
self.terminate\u event=threading.event()
self.start\u event=threading.event()
self.reset_event=threading.event()
self.count=self.timeout/self.sleep\u块
def运行(自):
打印('计时器:运行')
而不是自身。终止事件。是否设置了:
当self.count>0且self.start\u event.is\u set()时:
如果self.reset_event.wait(self.sleep_chunk):#等待一小段超时
self.reset_事件.clear()
self.count=self.timeout/self.sleep_chunk#重置
self.count-=1
如果self.count为0:
#处理串行数据的其余部分
#更新代码开始
#-如果self.idle\u timer.is\u live():
#-打印('取消计时器')
#-self.idle\u timer.cancel()
#更新代码结束
self.query\u thread=thread(target=lambda:self.show\u product\u info(条形码数据))
self.query\u thread.start()
定义初始化(自):
#定时器初始化
#-self.idle\u timer=定时器(5.0,self.show\u idle\u屏幕)
self.new\u线程=线程(目标=self.show\u idle\u屏幕)
self.new_thread.start()
root=应用程序()
root.mainloop()
日志:

计时器:已初始化
超时时间:6
超时:0.25
回拨:
启动计时器

经过反复尝试,我终于能够运行我想要的东西了

from threading import Thread, Timer

class TimerThread(threading.Thread):
    def __init__(self, timeout=3, sleep_chunk=0.25, callback=None, *args):
        threading.Thread.__init__(self)
        print('timer:initialized')
        self.timeout = timeout
        print('timeout:' + str(timeout))
        self.sleep_chunk = sleep_chunk
        print('timeout:' + str(sleep_chunk))
        if callback == None:
            self.callback = None
            print('callback:none')
        else:
            self.callback = callback
            print('callback:' + str(callback))
        self.callback_args = args

        self.terminate_event = threading.Event()
        self.start_event = threading.Event()
        self.reset_event = threading.Event()
        self.count = self.timeout/self.sleep_chunk

    def run(self):
        print('timer:run')
        while not self.terminate_event.is_set():
            while self.count > 0 and self.start_event.is_set():
                if self.reset_event.wait(self.sleep_chunk):  # wait for a small chunk of timeout
                    self.reset_event.clear()
                    self.count = self.timeout/self.sleep_chunk  # reset
                self.count -= 1
            if self.count <= 0:
                self.start_event.clear()
                print('timeout. calling function...')
                self.callback(*self.callback_args)
                self.count = self.timeout/self.sleep_chunk  # reset

    def start_timer(self):
        print('start_timer')
        self.start_event.set()

    def stop_timer(self):
        print('stop_timer')
        self.start_event.clear()
        self.count = self.timeout / self.sleep_chunk  # reset

    def restart_timer(self):
        # reset only if timer is running. otherwise start timer afresh
        print('restart_timer')
        if self.start_event.is_set():
            self.reset_event.set()
            print('restart_timer:reset')
        else:
            self.start_event.set()
            print('restart_timer:start')

    def terminate(self):
        print('terminate')
        self.terminate_event.set()

class Application(Tk):
    def show_idle_screen(self):
        for widget in self.winfo_children():
            widget.destroy()
        # Create new widget element
        print('idle_screen')

    def show_product_info(self, barcodeno):
        # call web api and get response
        # create information widget element
        # -Timer(5.0, self.show_idle_screen).start()
        # -tmr = TimerThread(timeout, sleep_chunk, Application().show_idle_screen)
        # -tmr.restart_timer()
        self.tmr.restart_timer()


    def serial_port_data_received(self):
        if self.serial.inWaiting() > 0:
            # The rest of handling serial data
            # UPDATED CODE START
            # -if self.idle_timer.is_alive():
            #     -print('cancelling timer')
            #     -self.idle_timer.cancel()
            # UPDATED CODE END
            self.query_thread = Thread(target=lambda: self.show_product_info(barcodedata))
            self.query_thread.start()


    def __init__(self):
            # Initialization of timer
            # -self.idle_timer = Timer(5.0, self.show_idle_screen)
            self.tmr = TimerThread(timeout, sleep_chunk, self.show_idle_screen)
            self.tmr.start()
            self.tmr.start_timer()
            self.new_thread = Thread(target=self.show_idle_screen)
            self.new_thread.start()

root = Application()
root.mainloop()

顺便说一句:
线程(target=self.show\u product\u info,args=(barcodedata,)
具有停止计时器的函数
cancel()。您必须停止计时器并创建新的
计时器
这是否回答了您的问题?(您问题的答案包含在问题中,您已经知道另一个问题的答案-如果这听起来令人困惑,请抱歉)@furas,让
args
出错
TypeError:show_product_info()接受2个位置参数,但给出了14个
from threading import Thread, Timer

class TimerThread(threading.Thread):
    def __init__(self, timeout=3, sleep_chunk=0.25, callback=None, *args):
        threading.Thread.__init__(self)
        print('timer:initialized')
        self.timeout = timeout
        print('timeout:' + str(timeout))
        self.sleep_chunk = sleep_chunk
        print('timeout:' + str(sleep_chunk))
        if callback == None:
            self.callback = None
            print('callback:none')
        else:
            self.callback = callback
            print('callback:' + str(callback))
        self.callback_args = args

        self.terminate_event = threading.Event()
        self.start_event = threading.Event()
        self.reset_event = threading.Event()
        self.count = self.timeout/self.sleep_chunk

    def run(self):
        print('timer:run')
        while not self.terminate_event.is_set():
            while self.count > 0 and self.start_event.is_set():
                if self.reset_event.wait(self.sleep_chunk):  # wait for a small chunk of timeout
                    self.reset_event.clear()
                    self.count = self.timeout/self.sleep_chunk  # reset
                self.count -= 1
            if self.count <= 0:
                self.start_event.clear()
                print('timeout. calling function...')
                self.callback(*self.callback_args)
                self.count = self.timeout/self.sleep_chunk  # reset

    def start_timer(self):
        print('start_timer')
        self.start_event.set()

    def stop_timer(self):
        print('stop_timer')
        self.start_event.clear()
        self.count = self.timeout / self.sleep_chunk  # reset

    def restart_timer(self):
        # reset only if timer is running. otherwise start timer afresh
        print('restart_timer')
        if self.start_event.is_set():
            self.reset_event.set()
            print('restart_timer:reset')
        else:
            self.start_event.set()
            print('restart_timer:start')

    def terminate(self):
        print('terminate')
        self.terminate_event.set()

class Application(Tk):
    def show_idle_screen(self):
        for widget in self.winfo_children():
            widget.destroy()
        # Create new widget element
        print('idle_screen')

    def show_product_info(self, barcodeno):
        # call web api and get response
        # create information widget element
        # -Timer(5.0, self.show_idle_screen).start()
        # -tmr = TimerThread(timeout, sleep_chunk, Application().show_idle_screen)
        # -tmr.restart_timer()
        self.tmr.restart_timer()


    def serial_port_data_received(self):
        if self.serial.inWaiting() > 0:
            # The rest of handling serial data
            # UPDATED CODE START
            # -if self.idle_timer.is_alive():
            #     -print('cancelling timer')
            #     -self.idle_timer.cancel()
            # UPDATED CODE END
            self.query_thread = Thread(target=lambda: self.show_product_info(barcodedata))
            self.query_thread.start()


    def __init__(self):
            # Initialization of timer
            # -self.idle_timer = Timer(5.0, self.show_idle_screen)
            self.tmr = TimerThread(timeout, sleep_chunk, self.show_idle_screen)
            self.tmr.start()
            self.tmr.start_timer()
            self.new_thread = Thread(target=self.show_idle_screen)
            self.new_thread.start()

root = Application()
root.mainloop()
idle_screen
timeout. calling function...
idle_screen
Going to query information for data
restart_timer
restart_timer:start
timeout. calling function...
idle_screen
Going to query information for data