2010-05-12 11 views
15

में धागे के बीच संचार मेरे पास एक धागा है जो कुछ डेटा (एक पायथन सूची) उत्पन्न करता है और जो विजेट के लिए उपलब्ध होगा जो मुख्य धागे में डेटा को पढ़ और प्रदर्शित करेगा। वास्तव में, मैं QMutex उपयोग कर रहा हूँ डेटा तक पहुँच प्रदान करने के लिए, इस तरह से:पायसाइड

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) 

ध्यान दें कि मैं के रूप में वे सामान्य डेटा हैं emit() में डेटा गुजर नहीं कर रहा हूँ (मैं के रूप में PyObject उपयोग करने का प्रयास डेटा प्रकार, लेकिन एक डबल free() प्रोग्राम को क्रैश करेगा), लेकिन मैं डेटा को deepcopy() के साथ कॉपी कर रहा हूं (माना जाता है कि डेटा इस तरह कॉपी किया जा सकता है)। मैं एक deepcopy() का इस्तेमाल किया क्योंकि मुझे लगता है कि है कि एक कोड की तरह:

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

केवल डेटा के लिए एक संदर्भ की नक़ल की (ना?) और डेटा साझा और वापसी के बाद खुला किया जाएगा ... है कोड सही है? यदि डेटा वास्तव में बड़ा है (जैसे 1'000'000 आइटम की सूची) तो मैं क्या कर सकता हूं?

धन्यवाद।

पीएस मैंने कुछ उदाहरण देखा, जैसे Qt Mandelbrot example, या threading example with PyQt, लेकिन वे स्लॉट में पैरामीटर के रूप में QImage का उपयोग करते हैं।

+0

, मुझे लगता है कि यहाँ एक दोष है: इस कोड क्योंकि काम कर सकते हैं slow_produce_data() एक ही समय में सभी डेटा लौटाता है, और उसके बाद ऑब्जेक्ट वैरिएबल को असाइन किया जाता है। कोई mutex का उपयोग नहीं किया जाता है क्योंकि डेटा संदर्भ एक बार में सेट किया जाता है (और मुझे लगता है कि सुरक्षित है), लेकिन अगर लूप में डेटा बनाया गया था, और अनुक्रम में बनाया गया था (यानी रिटर्न से नहीं), तो वहां एक म्यूटेक्स भी आवश्यक था। – AkiRoss

उत्तर

15

मुझे लगता है कि यह PySide के साथ काम करना चाहिए। काम नहीं करता है, तो एक छोटे से परीक्षण मामले से PySide बगजिला (http://bugs.openbossa.org/) पर एक बग रिपोर्ट करें: Btw

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) 
संबंधित मुद्दे