当我想发送无时,我在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,)
定义的。
我的问题是:这个问题有什么简单的解决方法吗?理想情况下只有一个信号?
答案 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')
)。我只是想更新这个,因为我遇到了同样的问题,发现了这个问题,后来发现了错误报告,解释了段错误。