I'm not sure how experienced you are with multithreaded programs, but 
here is some sample code (I mentioned it can get complicated).  I 
suggest you research Qt4 QThreads and also Qt4 Signals and slots to 
better understand the code below.  It is a working sample so you should 
be able to run it in a terminal and notice that the GUI is responsive 
and that you have messages being printed out on the terminal.  The code 
I provided below is more complicated than you may need for a 
proof-of-concept kind of program, but if you will be communicating with 
physical devices I suggest something like this.  I am by no means and 
expert, but I have been doing something similar to what you are doing.  
I also suggest maybe separating the device communication into another 
module/class, especially if others are going to (re)use your code.

Good Luck,
Dave

P.S. There are a lot of Qt4/PyQt4 threading examples online, but not all 
of them correct.  What I posted below is what I have found to be 
considered "correct" by most people.

#################
### Sample Code ###
#################

import time
from PyQt4 import QtGui,QtCore

class MyWindow(QtGui.QWidget):
     def __init__(self):
         QtGui.QWidget.__init__(self)

         # Sample GUI elements to test responsiveness
         the_choices = ["item"]*20
         self.choices = QtGui.QComboBox()
         self.choices.addItems(the_choices)
         self.layout = QtGui.QVBoxLayout(self)
         self.layout.addWidget(self.choices)
         self.setLayout(self.layout)

     def handle_new_data(self):
         # This is where you could redraw any matplotlib plots
         # Maybe send data through the signal/slot connection
         print "Updating data"

class MyInstrument(QtCore.QObject):
     signal_new_data = QtCore.pyqtSignal(name="signal_new_data")
     signal_closing = QtCore.pyqtSignal(name="signal_closing")
     def run(self):
         self._timer = QtCore.QTimer()
         self._timer.timeout.connect(self._run)
         self._timer.start(0)

     def _run(self):
         time.sleep(1)
         print "Running the instrument function"
         time.sleep(1)
         self.signal_new_data.emit()

     def close(self):
         print "Closing instrument thread"
         self._timer.stop()
         # Redundant timer stop
         self._timer.timeout.disconnect()
         self.signal_closing.emit()

if __name__ == "__main__":
     app = QtGui.QApplication([" "])
     w = MyWindow()
     w.show()
     instrument = MyInstrument()
     instrument_thread = QtCore.QThread()
     instrument.moveToThread(instrument_thread)

     instrument_thread.started.connect(instrument.run)
     instrument.signal_new_data.connect(w.handle_new_data)

     # Make the close function run in the main thread so you can 
"interrupt" the sleeps
     app.lastWindowClosed.connect(instrument.close, 
QtCore.Qt.DirectConnection)
     # You could also call quit "manually" after exec_() returns
     instrument.signal_closing.connect(instrument_thread.quit)

     instrument_thread.start()
     app.exec_()
     #instrument_thread.quit()

     print "Waiting for instrument thread..."
     instrument_thread.wait()
     print "SUCCESS"

######################
### End of Sample Code ###
######################

On 12/14/11 3:51 AM, Fabien Lafont wrote:
> I prefer to use the multi-thread method beacause it's easier for me
> and my colaborators to have the entire acquisition process at the same
> place. Until then I use a simple one but I hope to use a more complex
> one in few weeks ( put different voltages on different devices then
> measure many voltages or current). If I use the "domino" technique
> (call the next operation by the end of the previous) it can be complex
> to read and to edit. Thank you very much anyway!
>
> How can I write a multi-thread process? I've just tried to add
> qApp.processEvents() at the end of my while loop but it doesn't change
> anything...
>
> Thanks again,
>
> Fabien
>
> 2011/12/13 David Hoese<dho...@gmail.com>:
>> Yeah I didn't think about suggesting that, but I think it might get
>> complicated.  I think he would have to start a one shot timer to call a
>> function to set the voltage.  Then that function would also start another
>> one shot timer to call another function that would read from the sample.
>>   That function then would start a one shot timer to call the first function
>> again.  This way he can be sure that things are called in order and that
>> timing is consistent, just in case the GUI gets complicated or something
>> makes the event loop slow down.
>>
>> He could also use multiple threads.  Whatever works for Fabien I guess.
>>
>> -Dave
>>
>> On 12/13/11 1:00 PM, matplotlib-users-requ...@lists.sourceforge.net wrote:
>>> From: "Drain, Theodore R (343P)"<theodore.r.dr...@jpl.nasa.gov>
>>>
>>> Subject: Re: [Matplotlib-users] [ploting data] Live data
>>>
>>> Perhaps I'm missing something, but why not use QTimer?  You can't really
>>> every call sleep in a single threaded gui (for reasons you've encountered).
>>>   If you need to poll something, create a QTimer for 2 seconds and have it
>>> call a measurement function to update the data.  You shouldn't need any
>>> processEvents calls or sleep.
>>


------------------------------------------------------------------------------
Cloud Computing - Latest Buzzword or a Glimpse of the Future?
This paper surveys cloud computing today: What are the benefits? 
Why are businesses embracing it? What are its payoffs and pitfalls?
http://www.accelacomm.com/jaw/sdnl/114/51425149/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to