pyqt5使用apscheduler定时器遇到的一些坑

想用pyqt5写一个定时更新svn的软件,定时更新部分用到了apscheduler定时器,但是在写的过程中发现有很多的坑,这里简单的做一个记录。
这是软件的主界面,还未做界面美化,大致功能如图所示。
pyqt5使用apscheduler定时器遇到的一些坑_第1张图片
调度器分为六种,这里主要使用BlockingScheduler和BackgroundScheduler两种。
BlockingScheduler:适用于调度程序是进程中唯一运行的进程,调用start函数会阻塞当前线程,不能立即返回。
BackgroundScheduler:适用于调度程序在应用程序的后台运行,调用start后主线程不会阻塞。

在这里踩到第一个坑,使用BlockingScheduler调度器时候,会阻塞当前线程,pyqt5已经是一个线程,所以在pyqt5中使用调度器会被阻塞,直接崩掉。

  def svn_up(self):
        scheduler = BackgroundScheduler()
        i = 0
        week2idx = {'周一': 1, '周二': 2, '周三': 3, '周四': 4, '周五': 5, '周六': 6, '周日': 7}
        def job():
            os.system('cd ' + dir_path + ' && svn up ' + dir_path)

        while i < self.index:
            dir_path = self.table.item(i, 2).text()
            week = week2idx.get(self.table.item(i, 0).text())
            time = self.table.item(i, 1).text()
            scheduler.add_job(job, 'cron', day_of_week=week, hour=time.split(':')[0],
                              minute=time.split(':')[1])
            i += 1
        scheduler.start()

这里使用while循环,给scheduler添加多个job,但后续会有功能,对添加的job做删除,所以在添加定时任务的时候有两种方法:
1、

			scher= scheduler.add_job(job, 'cron', day_of_week=week, hour=time.split(':')[0],minute=time.split(':')[1])
			scher.remove()
      		将add_job实例化出来的对象直接进行remove。
 2、
			scheduler.add_job(job, 'cron', day_of_week=week, hour=time.split(':')[0],minute=time.split(':')[1],id='job_'+str(self.index-1))
           
			scheduler.remove_job("job_" + str(btn_idx))
			添加job时候给job一个id,这里的id需要用字符串,所以对数字进行str处理。

接下来就是遇到的第二个坑,虽然不是很难的问题,但是一直没找对思路,所以还是浪费了很多时间,这里做一下走弯路的经验教训。

def svn_up(self):
        scheduler = BackgroundScheduler()
        i = 0
        week2idx = {'周一': 1, '周二': 2, '周三': 3, '周四': 4, '周五': 5, '周六': 6, '周日': 7} ```

一开始,实例化scheduler,所以在scheduler.start(),即调度器启动后,因为使用了BackgroundScheduler类型调度器,所以job任务列表就已经进入后台运行,此时再次走进svn_up()函数,再次scheduler
= BackgroundScheduler()实例化一个调度器,想要通过之前添加任务的job_id去删除任务,会报错,找不到job_id。因为此时的scheduler
已经不是第一次启动的scheduler ,而是再次实例化的新scheduler ,即使两个scheduler
同名,也无法找到另一个scheduler 里的的任务。解决方法是svn_up()函数中不要初始化scheduler ,将scheduler
初始化放入整个程序init部分。

>     def __init__(self, parent=None):
        super(auto_svnup, self).__init__(parent)
        self.index = 0
        self.initUI()
        self.datatime_time = '00:00:00'
        self.datatime_week = '周一'
        self.scheduler = BackgroundScheduler()

你可能感兴趣的:(python)