可以传输任何值的PySide / PyQt信号(包括None)

时间:2014-01-13 22:23:36

标签: python qt pyqt pyside nonetype

当我想发送无时,我在PySide中使用Qt信号/插槽机制时遇到问题。

假设我有一个名为Calculator(QObject的子类)的类,它可以执行某些计算,其结果可以是任何类型,即任何类型的Python对象,甚至是None。我需要Calculator类的实例才能将结果发送给一些消费者对象(QObject的子类)。

我有什么:

class Calculator(QObject):
    finished = PySide.QtCore.Signal(object)  # object means it can transmit anything

    def calc(self):
        ... # calculation of the result
        self.finished.emit(result)

class Consumer(QObject):
    def __init__(self, calculator):
        ...
        calculator.finished.connect(self.consume)

    def consume(self, result):  # do something with the result
        ...

除了结果为None的情况外,此方法正常。然后程序在发出信号时崩溃。似乎None不是Python对象(可能是真的,我不是那么精通语言标准)。

现在我有一个解决方法,使用两个信号:

    finished = PySide.QtCore.Signal((),(object,))

    def calc(self):
        ... # calculation of the result
        if result is None:
            self.finished.emit()
        else:
            self.finished[object].emit(result)

此解决方案有效,但它很复杂,因为它要求使用者对象将信号链接两次。要么是两个插槽,要么是一个插槽,其中一个默认参数等于None。

class Consumer(QObject):
    def __init__(self, calculator):
        ...
        calculator.finished.connect(self.consume)
        calculator.finished[object].connect(self.consume)

    def consume(self, result=None):  # do something with the result
        ...

这很复杂,在创建许多不同的消费者类时容易出错。 我认为这个问题与PyQt是一样的,区别在于替代信号是使用列表[], [object]而不是元组(),(object,)定义的。

我的问题是:这个问题有什么简单的解决方法吗?理想情况下只有一个信号?

2 个答案:

答案 0 :(得分:1)

发布问题后,我找到了答案。所以我为回答我自己的问题而道歉 - 我知道它不是应该如何在StackOverflow上。我创建了一个名为ResultHolder的类,它封装了实际结果(结果是该类的成员变量)。然后我传输这个ResultHolder类的实例。其余的解决方案就是直截了当。

答案 1 :(得分:1)

顺便说一句,这个错误仍然存​​在于PySide中,它从版本1.2.1(从1.1.0开始就存在)中传输无信号时会出现段错误。有一个错误报告:

https://bugreports.qt-project.org/browse/PYSIDE-17

显然V.K。在一个单独的类中封装None的解决方案仍然可行,而选择另一种类型来传输(我将None切换到float('nan'))。我只是想更新这个,因为我遇到了同样的问题,发现了这个问题,后来发现了错误报告,解释了段错误。