У меня есть поток, который создает некоторые данные (список python) и которые должны быть доступны для виджета, который будет читать и отображать данные в основном потоке. На самом деле, я использую QMutex, чтобы обеспечить доступ к данным, таким образом:Связь между потоками в 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)
Обратите внимание, что я не передавая данные в emit()
, поскольку они являются общими данными (я пытался использовать PyObject, как тип данных, но двойной free()
приведет к сбою программы), но я копирую данные с помощью deepcopy()
(при условии, что данные могут быть скопированы следующим образом). я использовал DeepCopy(), потому что я думаю, что такой код:
def get_data(self):
QMutexLock(self.mutex)
return self.data
будет только скопировать ссылку на данные (? Справа) и данные будут доступны и разблокирован после возвращения ... ли это код правильный? Что делать, если данные действительно большие (например, список из 1'000'000 элементов)?
Спасибо.
P.S. Я видел несколько примеров, например, Qt Mandelbrot example или threading example with PyQt, но они используют QImage в качестве параметра в слотах.
Btw, я думаю, что есть недостаток здесь: этот код может работать, потому что slow_produce_data() возвращает все данные одновременно, а затем назначается переменной объекта. Мьютекс не используется, потому что ссылка на данные задается сразу (и я думаю, что это безопасно), но если данные были созданы в цикле и построены в последовательности (т. Е. Не из возврата), тогда там тоже был необходим мьютекс. – AkiRoss