PySide中线程之间的通信

时间:2010-05-12 22:06:22

标签: python multithreading pyqt pyqt4 pyside

我有一个产生一些数据的线程(一个python列表),它可用于一个小部件,它将读取并显示主线程中的数据。 实际上,我正在使用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项目列表),我该怎么办?

感谢。

P.S。我看到了一些示例,例如Qt Mandelbrot examplethreading example with PyQt,但它们在插槽中使用QImage作为参数。

1 个答案:

答案 0 :(得分:15)

我认为这应该适用于PySide。如果不行,请用一个小测试用例报告PySide bugzilla(http://bugs.openbossa.org/)上的一个错误:

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)