15

いくつかのデータ (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 を使用しようとしましたが、doublefree()はプログラムをクラッシュさせます) deepcopy()。このようにコピーされます)。次のようなコードだと思うので、 deepcopy() を使用しました。

def get_data(self):
  QMutexLock(self.mutex)
  return self.data

データへの参照のみをコピーし (右?)、データは共有され、戻り後にロック解除されます... このコードは正しいですか? データが非常に大きい場合 (1'000'000 項目のリストなど)、どうすればよいですか?

ありがとう。

PS Qt Mandelbrot examplePyQt を使用したスレッドの例など、いくつかの例を見ましたが、スロットのパラメーターとして QImage を使用しています。

4

1 に答える 1

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)
于 2010-11-20T13:18:59.640 に答える