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<dhoese@...287...>:
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-request@lists.sourceforge.net >>> wrote:
From: "Drain, Theodore R (343P)"<theodore.r.drain@...369...>
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.