教你搞一个比较简单的计时和进度条装饰器 (多线程进阶版)

简单的计时和进度条装饰器 - 多线程进阶版


上一篇关于装饰器的Blog

这个进阶版有什么?

在上一个装饰器工作时,跑了20秒后就停止了。如果运行的函数跑了60秒,后面的40秒我们是只能等到结束才知道一共运行了多少秒。在新的进阶版里,我们加入了多线程的功能来给进度条续命,以15秒为基础,15个跑完了续3个,直到结束为止。

话不多说上代码

def timer_pbar(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"{dt.now().strftime('%H:%M:%S')}")
        start = time.time()

        pbar = tqdm(
                total=15,
                bar_format='{l_bar}{bar:10}{r_bar}{bar:-10b}',
                desc=f"\rProcessing {func.__name__!r}",
                position=0,
                colour='#32CD32',   # limegreen HEX code
        )
        for i in range(15):
            if i < 15:
                time.sleep(1)
                pbar.update(1)

        # run the decorated function in a separated thread for extension
        from threading import Thread
        result = None
        def target():
            nonlocal result
            result = func(*args, **kwargs)
        thread = Thread(target=target)
        thread.start()

        # extend the progress bar if the function is still running
        while thread.is_alive():
            pbar.total += 3
            for i in range(3):
                pbar.update(1)
                time.sleep(1)

        pbar.close()
        end = time.time()
        print(f"运行时间{func.__name__!r}: {end - start:.3f}秒")
        return result
    return wrapper

效果图

进阶版的效果图
Dash Output

在DataSepll运行ipynb和PyCharm里运行DASH都看着还是可以的。

但是有个问题,其实函数是在15~18秒之间结束的,所以运行时间反映出来的是progresss_bar的时间,而不是函数的时间。希望大家注意哟,主要是多线程导致的。希望这篇blog对您有所帮助和启迪。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Qt提供了丰富的多线程编程支持,包括构造了一些基本的与平台无关的线程类、提交用户自定义事件的Thread-safe方式、多种线程间同步机制,如信号量、全局锁等。同时,Qt还提供了QTimer类,用于提供重复和单次定时。下面是关于Qt多线程和计时的介绍和演示: 1. Qt多线程的使用方法 Qt中的多线程编程主要通过QThread类实现。使用QThread类的步骤如下: (1)创建一个继承自QThread的子类,并重写其run()函数,run()函数中编写子线程的代码逻辑。 (2)在主线程中创建子线程对象,并调用其start()函数启动子线程。 下面是一个简单的例子,演示了如何使用QThread类创建一个子线程: ```python from PyQt5.QtCore import QThread, pyqtSignal class MyThread(QThread): # 定义一个信号,用于在子线程中发送消息给主线程 signal = pyqtSignal(str) def __init__(self, parent=None): super().__init__(parent) def run(self): # 子线程的代码逻辑 for i in range(5): self.signal.emit('当前进度:%d' % i) self.sleep(1) # 在主线程中创建子线程对象,并启动子线程 thread = MyThread() thread.signal.connect(lambda msg: print(msg)) thread.start() ``` 在上面的例子中,我们创建了一个继承自QThread的子类MyThread,并重写了其run()函数。在run()函数中,我们编写了子线程的代码逻辑,即每隔1秒钟向主线程发送一个消息。在主线程中,我们创建了子线程对象,并通过connect()函数将子线程的信号与一个lambda函数连接起来,当子线程发送信号时,lambda函数会被调用,输出消息。 2. QTimer的使用方法 QTimer类用于提供重复和单次定时。使用QTimer类的步骤如下: (1)创建一个QTimer对象,并设置定时的时间间隔。 (2)连接定时的timeout()信号到一个槽函数中,槽函数中编写定时触发时的代码逻辑。 (3)调用定时的start()函数启动定时。 下面是一个简单的例子,演示了如何使用QTimer类创建一个定时: ```python from PyQt5.QtCore import QTimer # 创建一个QTimer对象,并设置定时的时间间隔为1秒 timer = QTimer() timer.setInterval(1000) # 连接定时的timeout()信号到一个槽函数中 def on_timeout(): print('定时触发了') timer.timeout.connect(on_timeout) # 启动定时 timer.start() ``` 在上面的例子中,我们创建了一个QTimer对象,并设置了定时的时间间隔为1秒。然后,我们连接了定时的timeout()信号到一个槽函数on_timeout()中,当定时触发时,槽函数中的代码逻辑会被执行。最后,我们调用了定时的start()函数启动定时
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mike_Leigh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值