Mam wątek, który generuje pewne dane (lista pytonów) i który będzie dostępny dla widgetu, który odczyta i wyświetli dane w głównym wątku. Właściwie używam QMutex w celu zapewnienia dostępu do danych, w ten sposób:Komunikacja między wątkami w 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)
Należy pamiętać, że nie jestem przekazując dane w emit()
jak są dane generyczne (próbowałem użyć jako PyObject typ danych, ale podwójny free()
spowodowałby awarię programu), ale kopiuję dane za pomocą deepcopy()
(zakładając, że dane mogą być kopiowane w ten sposób). użyłem deepcopy(), ponieważ myślę, że kod jak:
def get_data(self):
QMutexLock(self.mutex)
return self.data
by skopiować tylko odniesienie do danych (? Po prawej), a dane będą udostępniane i odblokowane po powrocie ... Czy to kod poprawny? Co mogę zrobić, jeśli dane są naprawdę duże (jak lista 1 000 000 artykułów)?
Dzięki.
P.S. Widziałem kilka przykładów, takich jak Qt Mandelbrot example lub threading example with PyQt, ale używają QImage jako parametru w gniazdach.
Btw, myślę, że jest to wada tutaj: Ten kod może działać, ponieważ slowly_produce_data() zwraca wszystkie dane naraz, a następnie przypisuje je do zmiennej obiektu. Żaden muteks nie jest używany, ponieważ odniesienie do danych jest ustawiane na raz (i myślę, że jest bezpieczny), ale jeśli dane były produkowane w pętli i budowane w sekwencji (tj. Nie z powrotu), wówczas wymagany był również muteks. – AkiRoss