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.

Author: ekhumoro, 2010-05-13

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)
 15
Author: user514461,
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