【发布时间】:2020-09-15 00:41:57
【问题描述】:
我正在使用 PYQT5 构建一个 GUI,我正在使用 APScheduler 来管理我想要运行的作业。我将调度程序项和计时器项分解成自己的类,然后将它们连接到主文件中。
我遇到的问题是,一旦计时器完成一个周期,我尝试将时间添加到 Timer 类并重新开始它以进行下一次倒计时,然后调度程序应该再次运行。我收到两个错误或警告,我不知道如何解决它们。它们是:
QObject::killTimer: Timers cannot be stopped from another thread
QObject::startTimer: Timers cannot be started from another thread
一旦这些被抛出,GUI 更新但不再倒计时。我将附上我发现会重现错误的最简单版本。非常感谢您的任何帮助,并感谢您的宝贵时间。
Main.py
import sys
from PyQt5 import QtCore
from PyQt5 import QtWidgets
from Timer import Timer
from Schedule import Scheduler
import datetime
class MyMainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
vbox = QtWidgets.QVBoxLayout()
central_widget.setLayout(vbox)
self.start_pushButton = QtWidgets.QPushButton()
self.start_pushButton.setText("Start")
self.start_pushButton.clicked.connect(self.start_schedule)
vbox.addWidget(self.start_pushButton)
self.pages_qsw = QtWidgets.QStackedWidget()
vbox.addWidget(self.pages_qsw)
self.time_passed_qll = QtWidgets.QLabel()
vbox.addWidget(self.time_passed_qll)
self.my_timer = Timer()
self.my_timer.get_seconds.connect(self.update_gui)
self.sch = Scheduler()
def start_schedule(self):
self.sch.add(self.hello)
self.sch.start()
self.start_my_timer()
def start_my_timer(self):
next_run = self.sch.next_occurance().replace(tzinfo=None) # This removes the time zone.
a = datetime.datetime.now()
difference = next_run - a
self.my_timer.addSecs(difference.seconds)
self.my_timer.timer_start()
def hello(self):
print("hello world")
self.start_my_timer()
@QtCore.pyqtSlot(str)
def update_gui(self,seconds):
self.time_passed_qll.setText(str(seconds))
app = QtWidgets.QApplication(sys.argv)
main_window = MyMainWindow()
main_window.show()
sys.exit(app.exec_())
Timer.py
from PyQt5.QtCore import QTimer, pyqtSignal
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import datetime
class Timer(QTimer):
get_seconds = pyqtSignal(str)
def __init__(self):
super().__init__()
self.time_left = 1
self.timeout.connect(self.timer_timeout)
def addSecs(self, secs):
self.time_left += secs
def timer_start(self):
self.start(1000)
self.update_gui()
def timer_timeout(self):
self.time_left -= 1
if self.time_left <= 0:
self.stop()
self.update_gui()
def update_gui(self):
self.get_seconds.emit(str(self.time_left))
Schedule.py
from datetime import datetime
from apscheduler.schedulers.qt import QtScheduler
class Scheduler():
def __init__(self):
self.id = 'test_job'
self.sched = QtScheduler()
def add(self,job_function):
self.sched.add_job(job_function, 'cron', day_of_week='mon-fri',hour ='9-18',minute = '2,7,12,17,22,27,32,37,42,47,52,57',second = '5', id=self.id)
def start(self):
self.sched.start()
def next_occurance(self):
for job in self.sched.get_jobs():
if job.id == self.id:
return job.next_run_time
【问题讨论】:
标签: python python-3.x multithreading pyqt5 thread-safety