PySide声称Signals can be defined using the QtCore.Signal() class. Python types and C types can be passed as parameters to it. If you need to overload it just pass the types as tuples or lists
。从PySide Doc Signals and Slots in PySide开始,他们展示了一种创建多个信号的方法。那条线是:
# create two new signals on the fly: one will handle
# int type, the other will handle strings
speak = QtCore.Signal((int,), (str,))
我走得有点远,创造了这样的东西(用于学习目的):
speak = QtCore.Signal((int,), (str,), (tuple,), (list,), (A,), (B,), (Exception,), (unicode,), (float,))
A
和B
是我创建的两个不同的虚拟新样式类。然后我通过打印它们来调查实际创建的信号数量:
print someone.speak
print someone.speak[int]
print someone.speak[str]
print someone.speak[tuple]
print someone.speak[list]
print someone.speak[A]
print someone.speak[B]
print someone.speak[Exception]
print someone.speak[unicode]
print someone.speak[float]
我得到了这些:
<PySide.QtCore.SignalInstance object at 0x02179BA0>
<PySide.QtCore.SignalInstance object at 0x02179BA0>
<PySide.QtCore.SignalInstance object at 0x02179BB0>
<PySide.QtCore.SignalInstance object at 0x02179BC0>
<PySide.QtCore.SignalInstance object at 0x02179BC0>
<PySide.QtCore.SignalInstance object at 0x02179BC0>
<PySide.QtCore.SignalInstance object at 0x02179BC0>
<PySide.QtCore.SignalInstance object at 0x02179BC0>
<PySide.QtCore.SignalInstance object at 0x02179BB0>
<PySide.QtCore.SignalInstance object at 0x02179C00>
Obersevation:tuple
,list
,Exception
和我的自定义A
和B
获得相同的信号。我知道元组和列表有点普遍,PySide使用它来重载内容。但为什么我的A
和B
也会获得相同的信号?看起来只有像Python中的int
,float
和str
这样的原始类型才能获得新的信号。
有人可以解释这种奇怪的行为吗?
提前非常感谢!
[UPDATE]
当我在真正的PySide项目中遇到问题时,我做了上述探索。我将真实版本简化为:
#!/usr/bin/env python
import sys
from PySide import QtCore
class A(object):
def __init__(self, msg):
self.msg = msg
class B(object):
def __init__(self, msg):
self.msg = msg
@QtCore.Slot(A)
def sayA(a):
print 'From sayA:', a.msg
@QtCore.Slot(B)
def sayB(b):
print 'From sayB:', b.msg
class Communicate(QtCore.QObject):
speak = QtCore.Signal((A,), (B,))
someone = Communicate()
someone.speak[A].connect(sayA)
someone.speak[B].connect(sayB)
someone.speak[A].emit(A('A is good'))
someone.speak[B].emit(B('B is bad'))
它会打印出来:
From sayA: A is good
From sayB: A is good
From sayA: B is bad
From sayB: B is bad
我预计只会从sayA打印A is good
。
答案 0 :(得分:1)
请参阅this answer与您的问题相关的问题:
是可以用python对象定义信号,你可以使用:
signal_node_selected = QtCore.Signal(object)
我假设传递任何自定义Python类被视为传递object
。没有办法让信号区分它们。
答案 1 :(得分:0)
感谢您的研究!我遇到了同样的问题,并通过链接信号和使用备用名来携带不同的数据来解决这个问题:
class King(QtGui.QWidget):
summon = QtCore.Signal(str)
summon_knights = QtCore.Signal(object)
def __init__(self, parent=None):
super(King, self).__init__(parent=parent)
summon.connect(lambda x: self.summon_knights.emit(self.get_available_knights()))
def get_available_knights(self):
return ["Lancelot", "Galahad"]
lambda是为了处理或忽略召唤信号所携带的str。
这是我不那么优雅的划痕工作,向我自己证明它不像我想要的那样。由于异步信号/插槽行为导致它变得非常混乱(这对速度有利,但难以解释),因此睡眠会强制结果按时间顺序排列。
from PySide import QtCore
from PySide import QtGui
import sys
from collections import OrderedDict
from time import sleep
class Analyst(QtCore.QObject):
finished = QtCore.Signal((object,), (list,))
def __init__(self, parent=None):
super(Analyst, self).__init__(parent=parent)
self.number = 10000.0
def analyze(self):
print "Analyst working!"
result = OrderedDict()
result["a"] = self.number / 100.0
result["b"] = self.number / 200.0
sleep(1)
report = ['Analysis Report',
' a: {0}'.format(result["a"]),
' b: {0}'.format(result["b"])
]
print "Analyst done!"
self.finished[object].emit(result)
sleep(1)
self.finished[list].emit(report)
class Manager(QtCore.QObject):
announceStartWork = QtCore.Signal()
allDone = QtCore.Signal()
def __init__(self, parent=None):
super(Manager, self).__init__(parent=parent)
self.analyst = Analyst(self)
self.analyst.finished[object].connect(self.post_process)
self.analyst.finished[list].connect(self.report_result)
self.announceStartWork.connect(self.analyst.analyze)
self.reportsDone = False
self.resultsDone = False
self.allDone.connect(self.exitWhenReady)
def directAnalyst(self):
print "Telling analyst to start"
self.announceStartWork.emit()
def post_process(self, results):
print "Results type (expecting OrderedDict): {0}".format(type(results))
if issubclass(type(results), dict):
summation = 0
for value in results.values():
summation += value
print "Sum of Results: {0}".format(summation)
self.resultsDone = True
self.allDone.emit()
else:
print "*** WRONG TYPE! DICT slot got the LIST!"
def report_result(self, report):
print "Report type (expecting list): {0}".format(type(report))
if issubclass(type(report), list):
report_str = '\n'.join(report)
print "Report of original result: \n{0}".format(report_str)
self.reportsDone = True
self.allDone.emit()
else:
print "*** WRONG TYPE! LIST slot got the DICT!"
def exitWhenReady(self):
tasksCompleted = [self.reportsDone, self.resultsDone]
if all(tasksCompleted):
print "All tasks completed"
app.exit()
else:
print "Not all tasks completed yet"
if __name__ == "__main__":
app = QtCore.QCoreApplication([])
manager = Manager()
manager.directAnalyst()
sys.exit(app.exec_())
这是输出:
Telling analyst to start
Analyst working!
Analyst done!
Results type (expecting OrderedDict): <class 'collections.OrderedDict'>
Sum of Results: 150.0
Not all tasks completed yet
Report type (expecting list): <class 'collections.OrderedDict'>
*** WRONG TYPE! LIST slot got the DICT!
Results type (expecting OrderedDict): <type 'list'>
*** WRONG TYPE! DICT slot got the LIST!
Report type (expecting list): <type 'list'>
Report of original result:
Analysis Report
a: 100.0
b: 50.0
All tasks completed
好的,所以我在上面的管理器,分析师示例中实现了我自己的“修复”,并结束了这个:
from PySide import QtCore
from PySide import QtGui
import sys
from collections import OrderedDict
from time import sleep
class Analyst(QtCore.QObject):
finished_result = QtCore.Signal(object)
finished_report = QtCore.Signal(object)
_finished = QtCore.Signal(object)
def __init__(self, parent=None):
super(Analyst, self).__init__(parent=parent)
self.number = 10000.0
self._finished.connect(self._make_signal)
def analyze(self):
print "Analyst working!"
result = OrderedDict()
result["a"] = self.number / 100.0
result["b"] = self.number / 200.0
sleep(1)
report = ['Analysis Report',
' a: {0}'.format(result["a"]),
' b: {0}'.format(result["b"])
]
print "Analyst done!"
self._finished.emit(("result", result))
sleep(1)
self._finished.emit(("report", report))
def _make_signal(self, data):
if data[0] == "result":
self.finished_result.emit(data[1])
elif data[0] == "report":
self.finished_report.emit(data[1])
class Manager(QtCore.QObject):
announceStartWork = QtCore.Signal()
allDone = QtCore.Signal()
def __init__(self, parent=None):
super(Manager, self).__init__(parent=parent)
self.analyst = Analyst(self)
self.analyst.finished_result.connect(self.post_process)
self.analyst.finished_report.connect(self.report_result)
self.announceStartWork.connect(self.analyst.analyze)
self.reportsDone = False
self.resultsDone = False
self.allDone.connect(self.exitWhenReady)
def directAnalyst(self):
print "Telling analyst to start"
self.announceStartWork.emit()
def post_process(self, results):
print "Results type (expecting OrderedDict): {0}".format(type(results))
if issubclass(type(results), dict):
summation = 0
for value in results.values():
summation += value
print "Sum of Results: {0}".format(summation)
self.resultsDone = True
self.allDone.emit()
else:
print "*** WRONG TYPE! DICT slot got the LIST!"
def report_result(self, report):
print "Report type (expecting list): {0}".format(type(report))
if issubclass(type(report), list):
report_str = '\n'.join(report)
print "Report of original result: \n{0}".format(report_str)
self.reportsDone = True
self.allDone.emit()
else:
print "*** WRONG TYPE! LIST slot got the DICT!"
def exitWhenReady(self):
tasksCompleted = [self.reportsDone, self.resultsDone]
if all(tasksCompleted):
print "All tasks completed"
app.exit()
else:
print "Not all tasks completed yet"
if __name__ == "__main__":
app = QtCore.QCoreApplication([])
manager = Manager()
manager.directAnalyst()
sys.exit(app.exec_())
具有以下输出:
Telling analyst to start
Analyst working!
Analyst done!
Results type (expecting OrderedDict): <class 'collections.OrderedDict'>
Sum of Results: 150.0
Not all tasks completed yet
Report type (expecting list): <type 'list'>
Report of original result:
Analysis Report
a: 100.0
b: 50.0
All tasks completed