第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

PYQT5 線程與計(jì)劃和計(jì)時(shí)器的問題

PYQT5 線程與計(jì)劃和計(jì)時(shí)器的問題

蕪湖不蕪 2023-08-08 10:51:04
我正在使用它PYQT5來構(gòu)建 GUI,并使用它APScheduler來管理我想要運(yùn)行的作業(yè)。我將調(diào)度程序項(xiàng)目和計(jì)時(shí)器項(xiàng)目分解為自己的類,然后將它們連接到主文件中。我遇到的問題是,一旦計(jì)時(shí)器完成一個(gè)周期,我會(huì)嘗試為課程添加時(shí)間Timer,并在調(diào)度程序再次運(yùn)行之前重新開始下一次倒計(jì)時(shí)。我收到兩個(gè)錯(cuò)誤或警告,但我不知道如何修復(fù)它們。他們是:QObject::killTimer: Timers cannot be stopped from another threadQObject::startTimer: Timers cannot be started from another thread一旦拋出這些,GUI 就會(huì)更新,但不再倒計(jì)時(shí)。我將附上我發(fā)現(xiàn)的可以重現(xiàn)錯(cuò)誤的最簡單版本。非常感謝任何幫助,并感謝您的寶貴時(shí)間。Main.pyimport sysfrom PyQt5 import QtCorefrom PyQt5 import QtWidgetsfrom Timer import Timerfrom Schedule import Schedulerimport datetimeclass 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_())
查看完整描述

1 回答

?
繁花如伊

TA貢獻(xiàn)2012條經(jīng)驗(yàn) 獲得超12個(gè)贊

正如錯(cuò)誤所解釋的,您無法從另一個(gè)線程啟動(dòng)和停止 QTimer,并且由于 APScheduler 在不同的線程上工作,因此問題的原因:是self.hello從 APScheduler 線程調(diào)用的,而不是從創(chuàng)建計(jì)時(shí)器的線程調(diào)用的。


要訪問在不同線程中創(chuàng)建的對(duì)象,您需要使用信號(hào)和槽,以便讓 Qt 管理不同線程之間的通信。


因此,解決方案可能是通過繼承 QObject 來子類化您的 Scheduler(以便能夠創(chuàng)建信號(hào)并連接到它們),然后在每次執(zhí)行作業(yè)時(shí)使用自定義信號(hào)并使用該信號(hào)重新啟動(dòng)計(jì)時(shí)器。


為了實(shí)現(xiàn)這一目標(biāo),我使用了一個(gè)createJob實(shí)際運(yùn)行作業(yè)的函數(shù),并started在作業(yè)啟動(dòng)時(shí)發(fā)出信號(hào),并completed在作業(yè)完成時(shí)發(fā)出信號(hào)。


不幸的是,我無法測試以下代碼,因?yàn)槲椰F(xiàn)在無法安裝 APScheduler,但邏輯應(yīng)該沒問題。


Main.py


class MyMainWindow(QtWidgets.QMainWindow):

? ? def __init__(self):

? ? ? ? # ...

? ? ? ? self.sch = Scheduler()

? ? ? ? self.sch.completed.connect(self.start_my_timer)


? ? def hello(self):

? ? ? ? print("hello world")

? ? ? ? # no call to self.start_my_timer here!

Schedule.py


from datetime import datetime

from apscheduler.schedulers.qt import QtScheduler

from PyQt5 import QtCore


class Scheduler(QtCore.QObject):

? ? started = QtCore.pyqtSignal(object)

? ? completed = QtCore.pyqtSignal(object)

? ? def __init__(self):

? ? ? ? self.id = 'test_job'

? ? ? ? self.sched = QtScheduler()


? ? def add(self, job_function, *args, **kwargs):

? ? ? ? self.sched.add_job(self.createJob(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, *args, **kwargs)


? ? def createJob(self, job_function):

? ? ? ? def func(*args, **kwargs):

? ? ? ? ? ? self.started.emit(job_function)

? ? ? ? ? ? job_function(*args, **kwargs)

? ? ? ? ? ? self.completed.emit(job_function)

? ? ? ? return func


? ? 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

請(qǐng)注意,我使用參數(shù)(在您的情況下是對(duì)作業(yè)的引用)發(fā)出started和completed信號(hào),如果您想對(duì)多個(gè)作業(yè)做出不同的反應(yīng),這可能有助于識(shí)別作業(yè)。我還添加了對(duì)位置和關(guān)鍵字參數(shù)的基本支持。job_functionself.hello


另請(qǐng)注意,我僅提供一個(gè)非?;镜膶?shí)現(xiàn)(您的函數(shù)僅打印一條消息)。如果您需要與作業(yè)功能中的 UI 元素進(jìn)行交互,那么 QTimer 也會(huì)出現(xiàn)同樣的問題,因?yàn)椴辉试S從主 Qt 線程之外的線程訪問 UI 元素。


在這種情況下,您需要尋找另一種方法。例如,您可以添加一個(gè)作業(yè)(實(shí)際上并非從調(diào)度程序運(yùn)行)并以該作業(yè)作為參數(shù)發(fā)出信號(hào),然后連接到將在主線程中實(shí)際運(yùn)行該作業(yè)的函數(shù)。


Main.py


class MyMainWindow(QtWidgets.QMainWindow):

? ? def __init__(self):

? ? ? ? # ...

? ? ? ? self.sch = Scheduler()

? ? ? ? self.sch.startJob.connect(self.startJob)


? ? def startJob(self, job, args, kwargs):

? ? ? ? job(*args, **kwargs)

? ? ? ? self.start_my_timer()


? ? def hello(self):

? ? ? ? self.someLabel.setText("hello world")

Schedule.py


from datetime import datetime

from apscheduler.schedulers.qt import QtScheduler

from PyQt5 import QtCore


class Scheduler(QtCore.QObject):

? ? startJob = QtCore.pyqtSignal(object, object, object)

? ? # ...

? ? def add(self, job_function, *args, **kwargs):

? ? ? ? self.sched.add_job(self.createJob(job_function, args, kwargs), '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 createJob(self, job_function, args, kwargs):

? ? ? ? def func():

? ? ? ? ? ? self.starJob.emit(job_function, args, kwargs)

? ? ? ? return func

如前所述,上面的代碼未經(jīng)測試,您需要檢查可能的錯(cuò)誤(也許我在通配符參數(shù)上犯了一些錯(cuò)誤)。

最后,一些小建議:

  1. 實(shí)際上有必要使用裝飾器的情況非常少pyqtSlot;有趣的是,使用它們通常是問題或意外行為的根源。

  2. 通常最好保留信號(hào)參數(shù)原樣而不進(jìn)行任何轉(zhuǎn)換,因此您不應(yīng)將時(shí)間轉(zhuǎn)換為信號(hào)的字符串get_seconds;setNum()此外,QLabel 可以使用(浮點(diǎn)型和整數(shù)型)接受數(shù)值。

  3. 對(duì)空格要更加小心(我指的是self.sched.add_job):對(duì)于關(guān)鍵字參數(shù),空格只能存在于逗號(hào)之后;雖然它實(shí)際上并不代表問題,但它極大地提高了可讀性。


查看完整回答
反對(duì) 回復(fù) 2023-08-08
  • 1 回答
  • 0 關(guān)注
  • 286 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)