我使用信號和插槽來管理一些長時間運行的任務,以跟蹤進度等。我不得不啓動這樣一個運行類:PyQt/PySide沒有繼承的另一個對象的回聲信號
from PySide import QtCore, QtGui
class Run(QtCore.QObject):
running = QtCore.Signal(bool)
finished = QtCore.Signal(object)
status = QtCore.Signal(str)
message = QtCore.Signal(object)
progress = QtCore.Signal(float)
time_remaining_update = QtCore.Signal(str)
initialized = QtCore.Signal()
failed = QtCore.Signal(object)
pitch_update = QtCore.Signal(float)
def __init__(self, parent=None):
super().__init__(parent=parent)
#... rest of the class ...
最近我重構了一些東西,寫了一個任務類,其中包括一個運行實例作爲一個屬性。我想「回聲」上游的許多Run信號。這是我目前的解決方案:
class Task(QtCore.QObject):
#Signals echoed from Run
running = QtCore.Signal(bool)
status = QtCore.Signal(str)
message = QtCore.Signal(object)
progress = QtCore.Signal(float)
time_remaining_update = QtCore.Signal(str)
initialized = QtCore.Signal()
def __init__(self, run, parent=None):
super().__init__(parent=parent)
self.run = run
#Echo signals from run
signals = ['running', 'status', 'message', 'progress', 'time_remaining_update', 'initialized']
for signal in signals:
#Re-emit the signal
getattr(self.run, signal).connect(lambda *args: getattr(self, signal).emit(*args))
#... rest of class ...
我證實,lambda *args: func(*args)
模式將避免遞東西,如果沒有被傳遞到拉姆達,這是必要的服從不同的信號簽名FUNC。
這是處理從一個QObject到另一個QObject的「回聲」或「反彈」信號的最佳方式嗎?我基本上試圖保留一些運行API,同時用我的任務API更改/添加其他方面。
我意識到我可以通過繼承和重寫我想要更改的東西來獲得所有的運行API,但是我不想繼承子類,因爲任務處理失敗後重新啓動運行。我想將運行邏輯與處理重新啓動運行的代碼分開。也有運行信號和方法,我不想傳播任務。
我能想到的唯一更優雅的解決方案是自動創建任務信號......可能會創建一個echo_signals裝飾器,它接受一個QObject和一組信號名稱,然後執行這些事情?
是否有一個更優雅的實現這個Qt功能?有什麼建議麼?
所有這些間接性的目的是什麼?爲什麼不能使用Task類的消費者,例如'task.run.status.connect(處理器)'? (PS:在你當前的代碼中有一個bug,因爲'lambda'內的'signal'沒有被合適的範圍,你需要做'lambda * args,signal = signal:...')。 – ekhumoro 2014-10-02 00:16:19
謝謝 - 是的範圍問題給了我錯誤,我不明白,所以我放棄了這個想法。我目前的解決方案是按照你說的去做,並引用task.run。我想很容易嘗試變得聰明並且創造更多問題。 – flutefreak7 2014-10-02 00:23:58