Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Communication between threads in PySide

I have a thread which produces some data (a python list) and which shall be available for a widget that will read and display the data in the main thread. Actually, I'm using QMutex to provide access to the data, in this way:

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)

Note that I'm not passing the data in the emit() as they are generic data (I tried to use PyObject as data type, but a double free() would crash the program), but I'm copying the data with a deepcopy() (assuming the data can be copied like this). I used a deepcopy() because I guess that a code like:

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

would only copy a reference to the data (right?) and data would be shared AND unlocked after the return... Is this code correct? What can I do if data are really large (like a list of 1'000'000 items)?

Thanks.

P.S. I saw some examples, like the Qt Mandelbrot example, or the threading example with PyQt, but they use QImage as parameter in the slots.

like image 465
AkiRoss Avatar asked May 12 '10 22:05

AkiRoss


People also ask

How do you communicate data between threads?

Perhaps the safest way to send data from one thread to another is to use a Queue from the queue library. To do this, create a Queue instance that is shared by the threads. Threads then use put() or get() operations to add or remove items from the queue as shown in the code given below.

Can two threads in a process communicate?

Threads of the same process can communicate with each other through synchronization primitives like locks and semaphores, events like wait and notify, or through shared memory. The following illustration shows how a process (single-threaded) and a multi-threaded process share memory.

How do threads communicate with each other Python?

Python MultithreadUsing Event objects is the simple way to communicate between threads. An Event manages an internal flag that callers can either set() or clear(). Other threads can wait() for the flag to be set(). Note that the wait() method blocks until the flag is true.


1 Answers

I think this should work with PySide. if not work please report a bug on PySide bugzilla(http://bugs.openbossa.org/) with a small test case:

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)
like image 86
user514461 Avatar answered Oct 06 '22 12:10

user514461