利用python wxpython库实现计时器 (秒表)

       一个python小作业没想到引出这么多麻烦。要求是实现类似IPHONE手机得秒表计时,精确到小数点后两位(毫秒级),大概就是这种形式00:00.00,由分到毫秒。
       看到有得人用wx.Timer设置定时器,但都是以秒为最小单位得,参数设置为毫秒时,如timer.Start(10),10ms时就会发现计时器跑一分钟比正常时间慢了6s左右。
       又想到用time.time方法来,但是使用了while循环,页面刷新太快导致wx主界面卡死了,然后就一筹莫展。
       最后用了线程,把time.time方法放到线程里执行,只传回参数来更新页面。这样初步是可以了,但是还有几个后续问题。
       一个是还是会慢一些,大概会慢6s,但是可以通过修改代码解决,干脆不用tiem.time方法,只用while循环加sleep,每次时间加0.01s,但是sleep(0.009),少睡的0.001用于跑程序,因为1分钟大概误差6s,也就是6000ms,1分钟,程序更新时间的代码运行60000ms/10ms次,也就是6000次,6000次误差6000ms,每次误差1ms,也就是0.001s,所以sleep(0.01-0.001)。这样就弥补了误差,和正常时间无差。代码中有用来测试误差的备注代码,显示01:00.00时,时间戳结果为59.9820001125,这是不一定的,有时为59.99等,还是不错的精度(关于时间最关心的就是精度了,暂时最精确的时间是原子钟,为什么说暂时呢,因为原子钟过几十亿年也会产生1s误差,但是已经是人类能得到的最精确的时间了,机器会存在误差,关于时间精度的极限:没有最准,只有更准,这是我个人对于时间精度的理解)
       第二个是使用wx.statictext控件来更新时间的话会导致有闪烁,具体原因不太清楚,可能是控件界面更新太快了,试了下几种解决方法后干脆改成led显示,led数字也是wx自带的,解决了这个问题。
代码中有一些按钮的转换逻辑,以及添加了背景图片,以及利用sqlite3保存了数据,判断了计时上限,判断了保存状态等等等这些细节,可以自己看情况修改。
       下面直接上代码,基本都有注释,但是使用线程传递数据这点需要自己好好理解。
       下面展示完整代码
       https://blog.csdn.net/weixin_43141119/article/details/105239008 这个是不使用线程的其他做法 欢迎移步
(关于时间上的区别 我的做法显示的是连续的时间 但是会损失了精度 这个做法时间精确 但是显示的却是不连续的时间)

#coding = utf-8
import wx
import wx.gizmos as gizmos
import time
import threading
import os
import sqlite3

#返回一个唯一的事件类型ID赋值给EVT_RESULT_ID
EVT_RESULT_ID = wx.NewId()

#自定义一个事件类型,用于线程向主界面传递数据
class ResultEvent(wx.PyEvent):
    def __init__(self, data):
        wx.PyEvent.__init__(self)
        self.SetEventType(EVT_RESULT_ID)
        self.data = data
        
#自定义事件绑定函数,类似wx自带的wx.EVT_BUTTON
def EVT_RESULT(win, func):
    win.Connect(-1, -1, EVT_RESULT_ID, func)

#定义线程类
class WorkerThread(threading.Thread):
    def __init__(self, notify_window):
        threading.Thread.__init__(self)
        self._notify_window = notify_window
        self.resume_reset = 0#用于区分继续和重启线程
        self.__flag = threading.Event()#控制线程暂停或启动
        self.start()     
    #启动线程,循环计时
    def run(self):
        t = 0
        #测试一分钟误差代码
        #starttime = time.time()
        while True:
            t += 10
            mm = int((t/1000) / 60) 
            ss = int((t/1000) % 60)
            xx = int((t%1000) / 10)
            text_time = "{:02d}:{:02d}.{:02d}".format(mm,ss,xx)
            #if mm == 01 and ss == 00 and xx == 00:
            	#测试一分钟误差代码
                #print (time.time() - starttime)
                #self.__flag.clear()
            if mm == 59 and ss == 59 and xx == 99:
                self.__flag.clear()
            #向MainFrame传递时间
            wx.PostEvent(self._notify_window, ResultEvent(text_time))
            time.sleep(0.009)
            #重置秒表
            if self.resume_reset == 1:
                wx.PostEvent(self._notify_window, ResultEvent("00:00.00"))
                t = 0.0
                self
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值