python pyQt5 QTime的使用注意问题与python库time的相互影响
print打印与 python标准库的time问题
当使用python标准的time进行休眠时,会影响QTtime中激活的函数中的print打印,导致无法打印出任何信息。
如下为测试代码。这部分独立测试QTime
from PyQt5.QtCore import Qt
import time
import datetime
def test_print():
print(f"{datetime.datetime.now()} test_print ")
#with open(f'{datetime.datetime.now()}.txt','w') as f:
#f.close()
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
try:
print("start")
qtime = QTimer()
qtime.start(1000)
qtime.timeout.connect(test_print)
print(datetime.datetime.now())
time.sleep(5)
except Exception as e:
print(e)
sys.exit(app.exec_())
打印如图:
直接差了5s.那么在那5s内,QTimer的定时器调用是被暂停的!
原理上分析为: QTimer所在的UI线程(主线程)中的定时器,与python库的定时器可能在底层有耦合,操作python库的timer 进行休眠,会将主线程休眠,甚至会将QTimer的计时也休眠下去了。
`
我也猜测过是不是只是把printf函数的执行暂停了,其实像文件操作没有影响。所以故意写了一行错误代码,结果time.sleep(5) 执行的5s后,错误代码才报错。故证明并非只影响了printf的显示问题。
总结:
time.sleep 如果和QTimer所在的线程是同一个线程,将会导致QTime计时不准。
以下再附一个,封装的QTimer
附录 QTimer封装调用
class TimerTask(QObject):
def __init__(self,task_func,tick_count=None, over_func=None, args=[], kwargs={}):
super().__init__()
self.timer = QTimer(self)
self.timer.setTimerType(Qt.PreciseTimer)
self.timer.timeout.connect(self._tick)
self.task_func = task_func
self._args = args
self._kwargs = kwargs
self._tick_count = tick_count
self._cur_tick =0
self._over_func = over_func
def is_over(self):
if self._tick_count:
if self._cur_tick < self._tick_count:
return False
else:
return True
return False
def _tick(self):
try:
if self._tick_count:
if self._cur_tick < self._tick_count:
self._cur_tick += 1
self.task_func(*self._args, **self._kwargs)
else:
self.stop()
if self._over_func:
self._over_func()
else:
self.task_func(*self._args, **self._kwargs)
except Exception as e:
print("timer task error:",e)
self.timer.stop()
self.except_proc()
def start(self, ms, args=[], kwargs={}):
if args :
self._args = args
if kwargs:
self._kwargs = kwargs
self.timer.start(ms)
def stop(self):
self.timer.stop()
print("stop timer self")
def except_proc(self):
self.timer.stop()
def __del__(self):
print("timer del")