2013-07-30 3 views
1

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에서 한 번에 여러 신호를 생성하는 방법을 보여주었습니다. 그 라인은 다음과 같습니다PySide 신호가 Python 클래스를 오버로드 할 수 없습니다.

# 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,)) 

AB은 내가 만든 두 개의 서로 다른 더미 새로운 스타일 클래스됩니다. 그럼 실제로을 인쇄하여 만든 얼마나 많은 신호 연구 :

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 내 사용자 정의 AB있어 동일한 신호를 . 터플과리스트는 약간 일반적이고 PySide에서 물건을 오버로드하는 데 사용된다는 것을 알고 있습니다. 그러나 왜 내 AB도 같은 신호를 얻습니까? 파이썬에서 int, floatstr과 같은 진짜 원시 형식이 새 신호를 얻는 것처럼 보입니다.

누구나이 이상한 행동을 설명 할 수 있습니까?

미리 감사드립니다. 내가 진짜 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 

나는 A is good 만 사야에서 인쇄 할 것으로 예상.

답변

1

귀하의 질문과 관련된 질문에 this answer를 참조하십시오

예는 파이썬 객체와 신호를 정의 할 수 있습니다, 당신은 사용할 수 있습니다

signal_node_selected = QtCore.Signal (객체)

사용자 정의 Python 클래스를 전달하면 object을 전달하는 것으로 간주합니다. 신호로 구분할 수있는 방법이 없습니다.

+0

유효한 설명. 그래서 PySide는 파이썬 객체를 받아들이지 만 그것들을 구별하지는 않습니다. 고마워요! – foresightyj

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"] 

람다가 소환 신호에 의해 전달되는 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