From: David H. <dh...@gm...> - 2011-12-14 16:22:34
|
I don't know what you mean by "ApplicationWindow", is that a class or just a name for the main GUI window. I also don't really know what calling the graphical application means, but I'm sure the book can help you more than I can. Again, good luck. -Dave On 12/14/11 10:17 AM, Fabien Lafont wrote: > Thanks David, I start to read the Mark summerfield' book about PyQt > programming. > > In fact I realized I don't need multi-threading because I can remove > the Timer and just need to call the graphical application from the > while loop. > > How can I call the "ApplicationWindow" class from my while loop? I'll > try to read a bit more about PyQt to understand how it works :) > > thanks again! > > Fabien > > 2011/12/14 David Hoese<dh...@gm...>: >> 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<dh...@gm...>: >>>> 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, mat...@li... >>>> wrote: >>>>> From: "Drain, Theodore R (343P)"<the...@jp...> >>>>> >>>>> 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. >>>> |