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<[email protected]>:
>> 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, [email protected] wrote:
>>> From: "Drain, Theodore R (343P)"<[email protected]>
>>>
>>> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users