Komunikacja między wątkami w PySide
Mam wątek, który generuje pewne dane (listę Pythona) i który będzie dostępny dla widżetu, który będzie odczytywał i wyświetlał dane w głównym wątku. W rzeczywistości używam QMutex, aby zapewnić dostęp do danych, w ten sposób: {]}
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)
Zauważ, że nie przekazuję danych w emit()
, ponieważ są to DANE OGÓLNE(próbowałem użyć PyObject jako typu 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).
I użyłem deepcopy (), ponieważ domyślam się, że kod taki jak:
def get_data(self):
QMutexLock(self.mutex)
return self.data
Skopiowałby tylko odniesienie do danych (prawda?), a dane będą udostępniane i odblokowywane po powrocie... Czy ten kod jest prawidłowy? Co mogę zrobić, jeśli dane są naprawdę duże (jak lista 1'000'000 pozycji)?
Dzięki.P. S. widziałem kilka przykładów, jak przykład Qt Mandelbrot , lub przykład threading z PyQt , ale używają QImage jako parametru w slotach.
1 answers
Myślę, że to powinno zadziałać z PySide. jeśli nie działa to Zgłoś błąd na PySide bugzilla(http://bugs.openbossa.org/) z małym przypadkiem testowym:
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-20 13:18:59