PyQt / PySide在没有子类化的情况下回显另一个对象的信号

时间:2014-10-01 18:58:41

标签: python qt pyqt signals pyside

我使用信号和插槽管理一些长时间运行的任务来跟踪进度等。我有一个像这样开始的Run类:

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

我最近重构了一些东西并编写了一个Task类,其中包含一个Run实例作为属性。我想"回声"许多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,如果没有任何内容传递给lambda,这对于遵守不同的信号是必要的。签名。

这是处理"回声"的最佳方法吗?或者"弹跳"从一个QObject到另一个QObject的信号?我在使用Task API更改/添加其他方面时,基本上试图保留一些Run API。

我意识到我可以通过子类化和覆盖我想要更改的内容来获取所有Run API,但我不想要子类,因为Task在失败后处理重新启动运行。我希望将运行逻辑与处理重新启动运行的代码分开。还有一些我不想通过任务传播的运行信号和方法。

我能想到的唯一更优雅的解决方案是自动创建任务信号......也许制作一个echo_signals装饰器,它接受一个QObject和一个信号名称列表然后做这些事情?

是否有更优雅地实现此功能的Qt功能?有什么建议吗?

1 个答案:

答案 0 :(得分:0)

在Qt中,您可以将信号连接到其他信号,除非我遗漏了与您的示例相关的信息。