2010-05-12 5 views
15

일부 데이터 (파이썬 목록)를 생성하는 스레드가 있고 주 스레드에서 데이터를 읽고 표시하는 위젯에 사용할 수있는 스레드가 있습니다. 사실 , 나는 이런 식으로, 데이터에 대한 액세스를 제공하는 QMutex을 사용하고 있습니다 : 그들은 일반 데이터가 나는이 emit()에 데이터를 전달하고 있지 않다PySide의 스레드 간 통신

class Thread(QThread): 
    def get_data(self): 
    QMutexLock(self.mutex) 
    return deepcopy(self.data) 

    def set_data(self, data): 
    QMutexLock(self.mutex) 
    self.data = deepcopy(data) 

    def run(self): 
    self.mutex = QMutex() 
    while True: 
     self.data = slowly_produce_data() 
     self.emit(SIGNAL("dataReady()")) 

class Widget(QWidget): 
    def __init__(self): 
    self.thread = Thread() 
    self.connect(self.thread, SIGNAL("dataReady()"), self.get_data) 
    self.thread.start() 

    def get_data(self): 
    self.data = self.thread.get_data() 

    def paintEvent(self, event): 
    paint_somehow(self.data) 

주 (나는대로의 PyObject를 사용하려고 데이터 형식은 double free()이 프로그램을 중단 시키지만) deepcopy() (데이터를 이와 같이 복사 할 수 있다고 가정) 데이터를 복사하고 있습니다.

def get_data(self): 
    QMutexLock(self.mutex) 
    return self.data 

데이터 만에 대한 참조를 복사합니다 (? 오른쪽)과 데이터 공유 및 반환 후 해제 될 ... 인가이 : 그 코드 등을 생각하기 때문에 은 내가 deepcopy()를 사용 코드가 맞습니까? 데이터가 실제로 커지면 어떻게해야합니까? (예 : 1'000'000 항목 목록)?

감사합니다.

P. Qt Mandelbrot example 또는 threading example with PyQt과 같은 몇 가지 예제를 보았지만 슬롯의 매개 변수로 QImage를 사용합니다.

+0

을, BTW 나는 여기에 결함이 있다고 생각 slowly_produce_data()는 모든 데이터를 한 번에 반환 한 다음 객체 변수에 할당합니다. 뮤텍스는 데이터 참조가 한 번에 설정 되었기 때문에 사용되지 않습니다.하지만 데이터가 루프에서 생성되고 시퀀스 (즉, 반환되지 않음)로 작성된 경우 뮤텍스가 필요합니다. – AkiRoss

답변

15

저는 이것이 PySide와 함께 작동해야한다고 생각합니다. 작은 테스트 케이스와 PySide 버그질라 (http://bugs.openbossa.org/)에 버그를보고하십시오 작동하지 않을 경우이 코드가 있기 때문에 작동 할 수 있습니다

class Thread(QThread): 
    dataReady = Signal(object) 

    def run(self): 
    while True: 
     self.data = slowly_produce_data() 
     # this will add a ref to self.data and avoid the destruction 
     self.dataReady.emit(self.data) 

class Widget(QWidget): 
    def __init__(self): 
    self.thread = Thread() 
    self.thread.dataReady.connect(self.get_data, Qt.QueuedConnection) 
    self.thread.start() 

    def get_data(self, data): 
    self.data = data 

    def paintEvent(self, event): 
    paint_somehow(self.data)