سؤال

لدي مؤشر ترابط ينتج بعض البيانات (قائمة 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 عناصر)؟

شكرًا.

ملاحظة: رأيت بعض الأمثلة ، مثل QT Mandelbrot مثال, ، أو ال مثال على الخيوط مع PYQT, ، لكنهم يستخدمون Qimage كمعلمة في الفتحات.

هل كانت مفيدة؟

المحلول

أعتقد أن هذا يجب أن يعمل مع بيسايد. إذا لم يكن العمل ، فيرجى الإبلاغ عن خطأ في بيسايد بوجزيلا (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)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top