[PySide] using QProcess to run python function

Frank Rueter | OHUfx frank at ohufx.com
Thu Jul 23 06:05:05 CEST 2015


Hi all,

once again I got dragged away from this for ages,my apologies.
I am still trying to get all the stdout from other python functions to 
print to a QPlainTextWidget.
I left off with a modified example of Sean's code below and am realising 
that the issue is that I don't have an event loop in my worker's run() 
method. My run() looks like this:

class Worker(QtCore.QObject, QtCore.QRunnable):
     processed = QtCore.Signal(int)
     curProcess = QtCore.Signal(str)
     finished = QtCore.Signal()

     def __init__(self, parent=None):
         QtCore.QObject.__init__(self, parent)
         QtCore.QRunnable.__init__(self, parent)

     def run(self):
         self.curProcess.emit('starting processing')
*        dummyFunction() # need to grab output from this as it runs*
         self.curProcess.emit('current process...')
         self.finished.emit()

The question is how do I emit the stdout from dummyFunction() while it's 
running (it takes a minute or so to finish all sorts of tasks)? Do I 
have to move it to an extra thread again and connect to that?

Cheers,
frank



On 14/03/14 6:39 pm, Sean Fisk wrote:
>
> Hi Frank,
>
> I’ve modified the earlier example to display the progress in the best 
> way that I know. It doesn’t use the |finished| signal, but it should 
> be pretty easy to adapt it to your needs. Let me know if this is what 
> you want! [Either way, it’s fun to click it a bunch of times :) ]
>
> Cheers,
>
> - Sean
>
> |#!/usr/bin/env python
>
> import  sys
> import  time
>
> from  PySideimport  QtGui
> from  PySideimport  QtCore
>
> TOTAL_WIDGETS =10
>
> class  Worker(QtCore.QRunnable, QtCore.QObject):
>      processed = QtCore.Signal(int)
>      finished = QtCore.Signal()
>
>      def  __init__(self, parent=None):
>          # IMPORTANT: We must call the constructors of *both* parents.
>          QtCore.QObject.__init__(self, parent)
>          QtCore.QRunnable.__init__(self, parent)
>
>      def  run(self):
>          for  iin  xrange(TOTAL_WIDGETS):
>              # We sleep first to simulate an operation taking place.
>              time.sleep(0.5)
>              print  'Thread: {0}, Processed: {1}'.format(
>                  QtCore.QThread.currentThread(), i)
>              self.processed.emit(i +1)
>          # Must manually emit the finished signal.
>          self.finished.emit()
>
> class  MainWindow(QtGui.QWidget):
>      def  __init__(self, parent=None):
>          super(MainWindow, self).__init__(parent)
>          self._thread_pool = QtCore.QThreadPool.globalInstance()
>
>          # IMPORTANT: Don't quit the app until the thread has completed.
>          # Prevents errors like:
>          #
>          #     QThread: Destroyed while thread is still running
>          #
>          # QThreadPool.waitForDone() is, unfortunately, not a slot.
>          QtGui.QApplication.instance().aboutToQuit.connect(
>              lambda: self._thread_pool.waitForDone())
>
>          self._layout = QtGui.QVBoxLayout(self)
>          self._add_button = QtGui.QPushButton('Start New Task')
>          self._layout.addWidget(self._add_button)
>
>          self._add_button.clicked.connect(self._start_new_task)
>
>      def  _start_new_task(self):
>          task = Worker()
>          progress_bar = QtGui.QProgressBar()
>          progress_bar.setRange(0, TOTAL_WIDGETS)
>          task.processed.connect(progress_bar.setValue)
>          self._layout.addWidget(progress_bar)
>          self._thread_pool.start(task)
>
> if  __name__ =='__main__':
>      app = QtGui.QApplication(sys.argv)
>      window = MainWindow()
>      window.show()
>      window.raise_()
>      raise  SystemExit(app.exec_())
> |
>
>
> --
> Sean Fisk
>
>
> On Fri, Mar 14, 2014 at 12:27 AM, Frank Rueter | OHUfx 
> <frank at ohufx.com <mailto:frank at ohufx.com>> wrote:
>
>     great, thanks Sean.
>     In order to communicate with the progress in each thread (to drive
>     progress and catch finished and error events), should I use
>     QtCore.QThread.currentThread() and hook up my slots to it's events?
>
>     Cheers and thanks a lot for bearing with me here.
>
>     frank
>
>
>
>     On 14/03/14 17:15, Sean Fisk wrote:
>>
>>     Hi Frank,
>>
>>     Glad you got that figured out. One more important thing:
>>
>>     To achieve a “clean exit”, you should wait for the completion of
>>     all tasks associated with the |QThreadPool| before exiting. Use
>>     something like:
>>
>>     |thread_pool = QtCore.QThreadPool.globalInstance()
>>     thread_pool.start(hello)
>>     thread_pool.waitForDone()
>>     |
>>
>>     It is a common idiom to have the application wait for this before
>>     it exits:
>>
>>     If you are using a |QApplication| or |QCoreApplication| (i.e., a
>>     Qt event loop):
>>
>>     |from  PySideimport  QtCore
>>     QtCore.QCoreApplication.instance().aboutToQuit.connect(thread_pool.waitForDone)
>>     |
>>
>>     Or with Python’s exit handlers:
>>
>>     |import  atexit
>>     atexit.register(thread_pool.waitForDone)
>>     |
>>
>>     In general, I would prefer Qt’s method if you are running an
>>     event loop.
>>
>>     Hope this helps!
>>
>>
>>
>>     --
>>     Sean Fisk
>>
>>
>>     On Fri, Mar 14, 2014 at 12:00 AM, Frank Rueter | OHUfx
>>     <frank at ohufx.com <mailto:frank at ohufx.com>> wrote:
>>
>>         False alarm:
>>         Looks like the culprit wasn't the code but the debugger I was
>>         using spat it's dummy more or less silently.
>>         When I run the same code in a different interpreter it works
>>         as expected.
>>
>>
>>
>>
>>         On 14/03/14 14:30, Frank Rueter | OHUfx wrote:
>>>         after a much longer absence from this than anticipated, I'm
>>>         finally trying to get back into this.
>>>         I had a look at your example Sean and it makes sense so far.
>>>         Now I'm trying to follow your advise and use QThreadPool,
>>>         but am not finding any good examples on it's usage.
>>>         Unfortunately, the first example mentioned in the docs
>>>         <http://srinikom.github.io/pyside-docs/PySide/QtCore/QThreadPool.html>
>>>         already throws an error for me:
>>>
>>>         from PySide import QtCore
>>>         class HelloWorldTask(QtCore.QRunnable):
>>>             def run(self):
>>>                 print "Hello world from thread",
>>>         QtCore.QThread.currentThread()
>>>
>>>         hello = HelloWorldTask()
>>>         # QThreadPool takes ownership and deletes 'hello' automatically
>>>         QtCore.QThreadPool.globalInstance().start(hello)
>>>
>>>         result:
>>>         Hello world from thread
>>>         Traceback (most recent call last):
>>>           File
>>>         "/ohufx/pipeline/tools/python/sandbox/QThreadPoolTest.py",
>>>         line 6, in run
>>>             print "Hello world from thread",
>>>         QtCore.QThread.currentThread()
>>>         AttributeError: 'NoneType' object has no attribute 'QThread'
>>>
>>>
>>>
>>>         What am I missing here?
>>>
>>>         Cheers,
>>>         frank
>>>
>>>
>>>
>>>
>>>
>>>         On 28/01/14 08:00, Sean Fisk wrote:
>>>>         On Sat, Jan 25, 2014 at 2:38 AM, Frank Rueter | OHUfx
>>>>         <frank at ohufx.com <mailto:frank at ohufx.com>> wrote:
>>>>
>>>>             fantastic, thanks Sean!!
>>>>             I will examine this to make sure I understand
>>>>             everything, then give QThreadPool a whirl. Am more than
>>>>             happy to learn from more experienced people and adjust
>>>>             my approaches accordingly, so thanks a lot for your
>>>>             time with this!
>>>>
>>>>
>>>>         No problem! Let me know if you have any questions about the
>>>>         code.
>>>>
>>>>
>>>>             Cheers,
>>>>             frank
>>>>
>>>>
>>>>
>>>>             On 25/01/14 20:03, Sean Fisk wrote:
>>>>>
>>>>>             Hi Frank,
>>>>>
>>>>>             I updated your example to hopefully work as you would
>>>>>             like. I added a progress bar update as well. I’m going
>>>>>             to make a last-ditch effort to convince you to stop
>>>>>             doing things manually with |QThread|, and move to
>>>>>             using |QThreadPool|
>>>>>             <http://pyside.github.io/docs/pyside/PySide/QtCore/QThreadPool.html>.
>>>>>             Everything about the |QThreadPool| API is much nicer,
>>>>>             and it’s worked much better for me in real projects.
>>>>>             Also, the Python ‘s |multiprocessing|
>>>>>             <http://docs.python.org/2/library/multiprocessing.html> and
>>>>>             |concurrent.futures|
>>>>>             <http://pythonhosted.org/futures/> modules can work
>>>>>             well if you’re careful about your callbacks.
>>>>>
>>>>>             Also, there is a large discussion about not overriding
>>>>>             the |run()| method of |QThread|. I don’t think
>>>>>             overriding it is so bad if you don’t need the thread
>>>>>             to be running an event loop of its own. I still prefer
>>>>>             the |QThreadPool| API, though. Someone please correct
>>>>>             me if this is totally wrong and there is never a
>>>>>             reason to override it.
>>>>>
>>>>>             Here is the code:
>>>>>
>>>>>             |#!/usr/bin/env python
>>>>>
>>>>>             import  sys
>>>>>             import  time
>>>>>
>>>>>             from  PySideimport  QtGui
>>>>>             from  PySideimport  QtCore
>>>>>
>>>>>             TOTAL_WIDGETS =10
>>>>>
>>>>>             class  Worker(QtCore.QObject):
>>>>>                  processed = QtCore.Signal(int)
>>>>>                  finished = QtCore.Signal()
>>>>>
>>>>>                  # Overriding this is not necessary if you're not doing anything in it.
>>>>>
>>>>>                  # def __init__(self):
>>>>>                  #     super(Worker, self).__init__()
>>>>>
>>>>>                  def  helloWorld(self):
>>>>>                      for  iin  xrange(TOTAL_WIDGETS):
>>>>>                          # We sleep first to simulate an operation taking place.
>>>>>                          time.sleep(0.5)
>>>>>                          print  'hello %s'  % i
>>>>>                          self.processed.emit(i +1)
>>>>>                      # Must manually emit the finished signal.
>>>>>                      self.finished.emit()
>>>>>
>>>>>             class  MainUI(QtGui.QWidget):
>>>>>                  def  __init__(self, parent=None):
>>>>>                      super(MainUI, self).__init__(parent)
>>>>>                      self.extraThread = QtCore.QThread()
>>>>>
>>>>>                      # IMPORTANT: Don't quit the app until the thread has completed. Prevents errors like:
>>>>>                      #
>>>>>                      #     QThread: Destroyed while thread is still running
>>>>>                      #
>>>>>                      QtGui.QApplication.instance().aboutToQuit.connect(self.quit)
>>>>>
>>>>>                      self.worker = Worker()
>>>>>                      self.worker.moveToThread(self.extraThread)
>>>>>                      self.setupUI()
>>>>>                      self.connectSignalsAndSlots()
>>>>>
>>>>>                  def  setupUI(self):
>>>>>                      # CREAT MAIN LAYOUT AND WIDGETS
>>>>>                      mainLayout = QtGui.QVBoxLayout()
>>>>>                      btnLayout = QtGui.QHBoxLayout()
>>>>>                      mainLayout.addLayout(btnLayout)
>>>>>                      self.setLayout(mainLayout)
>>>>>
>>>>>                      self.progressBar = QtGui.QProgressBar(self)
>>>>>                      self.progressBar.setRange(0, TOTAL_WIDGETS)
>>>>>                      self.progressBar.setVisible(False)
>>>>>                      self.btnWork = QtGui.QPushButton('Do Work')
>>>>>                      self.btnCancel = QtGui.QPushButton('Cancel')
>>>>>                      self.btnCancel.setDisabled(True)
>>>>>
>>>>>                      self.guiResponseProgressbar = QtGui.QProgressBar(self)
>>>>>                      self.guiResponseProgressbar.setRange(0,0)
>>>>>
>>>>>                      self.outputWindow = QtGui.QTextEdit()
>>>>>
>>>>>                      mainLayout.addWidget(self.progressBar)
>>>>>                      mainLayout.addWidget(self.outputWindow)
>>>>>                      mainLayout.addWidget(self.guiResponseProgressbar)
>>>>>
>>>>>                      btnLayout.addWidget(self.btnWork)
>>>>>                      btnLayout.addWidget(self.btnCancel)
>>>>>
>>>>>                  def  connectSignalsAndSlots(self):
>>>>>                      print  'connecting signals'
>>>>>                      self.btnWork.clicked.connect(self.startWorker)
>>>>>
>>>>>                      # Pleas see <http://nooooooooooooooo.com/>. Bad bad bad bad bad.
>>>>>                      # self.btnCancel.clicked.connect(self.extraThread.terminate)
>>>>>
>>>>>                      # THREAD STARTED
>>>>>                      # Not necessary; just do this in startWorker.
>>>>>                      # self.extraThread.started.connect(lambda: self.btnWork.setDisabled(True))
>>>>>                      # self.extraThread.started.connect(lambda: self.btnCancel.setEnabled(True))
>>>>>                      # self.extraThread.started.connect(self.progressBar.show)
>>>>>                      self.extraThread.started.connect(self.worker.helloWorld)
>>>>>
>>>>>                      # THREAD FINISHED
>>>>>                      # self.extraThread.finished.connect(lambda: self.btnCancel.setDisabled(True))
>>>>>                      # self.extraThread.finished.connect(self.extraThread.deleteLater)
>>>>>                      # self.extraThread.finished.connect(self.worker.deleteLater)
>>>>>                      self.extraThread.finished.connect(self.finished)
>>>>>
>>>>>                      # Connect worker signals.
>>>>>                      self.worker.processed.connect(self.progressBar.setValue)
>>>>>                      self.worker.finished.connect(self.finished)
>>>>>
>>>>>                      # SHOW PROGRESS BAR WHEN PUBLISHING STARTS
>>>>>                      # self.extraThread.started.connect(self.progressBar.show)
>>>>>                      # CONNECT PROCESS TO PROGRESS BAR AND OUTPUT WINDOW
>>>>>                      # NOT DONE YET
>>>>>
>>>>>                  def  startWorker(self):
>>>>>                      # GO
>>>>>                      self.btnWork.setDisabled(True)
>>>>>                      self.btnCancel.setEnabled(True)
>>>>>                      self.progressBar.show()
>>>>>                      print  'starting worker thread'
>>>>>                      self.extraThread.start()
>>>>>
>>>>>                      # THIS IS BLOCKING THE GUI THREAD! Try putting this back in and seeing
>>>>>                      # what happens to the gui_response_progressbar.
>>>>>
>>>>>                      # for i in xrange(10):
>>>>>                      #     print 'from main thread:', i
>>>>>                      #     time.sleep(.3)
>>>>>
>>>>>                  def  finished(self):
>>>>>                      print  'finished'
>>>>>                      self.btnCancel.setDisabled(True)
>>>>>                      # self.extraThread.deleteLater()
>>>>>                      # self.worker.deleteLater()
>>>>>
>>>>>                  def  quit(self):
>>>>>                      # Quit the thread's event loop. Note that this *doesn't* stop tasks
>>>>>                      # running in the thread, it just stops the thread from dispatching
>>>>>                      # events.
>>>>>                      self.extraThread.quit()
>>>>>                      # Wait for the thread to complete. If the thread's task is not done,
>>>>>                      # this will block.
>>>>>                      self.extraThread.wait()
>>>>>
>>>>>             if  __name__ =='__main__':
>>>>>                  args = sys.argv
>>>>>                  app = QtGui.QApplication(args)
>>>>>                  p = MainUI()
>>>>>                  p.show()
>>>>>                  # Annoyance on Mac OS X.
>>>>>                  p.raise_()
>>>>>                  sys.exit(app.exec_())|
>>>>>
>>>>>             Cheers,
>>>>>
>>>>>
>>>>>
>>>>>             --
>>>>>             Sean Fisk
>>>>>
>>>>>
>>>>>             On Sat, Jan 25, 2014 at 12:30 AM, Frank Rueter | OHUfx
>>>>>             <frank at ohufx.com <mailto:frank at ohufx.com>> wrote:
>>>>>
>>>>>                 quick update:
>>>>>                 I just learnt about connection types but those
>>>>>                 didn't help either in this case:
>>>>>                 http://qt-project.org/doc/qt-5/threads-qobject.html#signals-and-slots-across-threads
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>                 On 25/01/14 18:15, Frank Rueter | OHUfx wrote:
>>>>>>                 And of course I ran into trouble :-D
>>>>>>                 Here is my test code trying to ustilise QThread:
>>>>>>                 http://pastebin.com/Q26Q9M1M
>>>>>>
>>>>>>                 The basic structure seems to work (the extra
>>>>>>                 thread and the main thread are running at the
>>>>>>                 same time), but my UI does not update according
>>>>>>                 to the signal connections, e.g.:
>>>>>>                 When the thread starts the progress bar is
>>>>>>                 supposed to be shown, the "Do Work" button should
>>>>>>                 be disabled, the "Cancel" button disabled.
>>>>>>                 etc.
>>>>>>
>>>>>>                 I tried calling self.update() in the MainUI when
>>>>>>                 the thread starts but to no avail.
>>>>>>                 I'm sure I'm missing something obvious as usual.
>>>>>>
>>>>>>                 I tried to adhere to what I learnt on this list
>>>>>>                 about threading and avoid sub-classing QThread.
>>>>>>
>>>>>>                 Cheers,
>>>>>>                 frank
>>>>>>
>>>>>>                 On 24/01/14 17:41, Frank Rueter | OHUfx wrote:
>>>>>>>                 Great, thanks. I shall adjust my code.
>>>>>>>                 I am interested in seeing how you would go about
>>>>>>>                 it, but let me have a go from scratch, I will be
>>>>>>>                 able to understand things much better afterwards :)
>>>>>>>
>>>>>>>                 Cheers,
>>>>>>>                 frank
>>>>>>>
>>>>>>>
>>>>>>>                 On 24/01/14 17:38, Sean Fisk wrote:
>>>>>>>>                 On Thu, Jan 23, 2014 at 10:44 PM, Frank Rueter
>>>>>>>>                 | OHUfx <frank at ohufx.com
>>>>>>>>                 <mailto:frank at ohufx.com>> wrote:
>>>>>>>>
>>>>>>>>                     Much appreciated but as I mentioned, I
>>>>>>>>                     think I jumped the gun with my post and
>>>>>>>>                     should be using QThread to hook the python
>>>>>>>>                     code to my QProgressBar and debug output
>>>>>>>>                     window (QTextEdit).
>>>>>>>>
>>>>>>>>                 That would be a correct way to use
>>>>>>>>                 |QProgressBar|. Also, for subprocess output, I
>>>>>>>>                 would consider using |QPlainTextEdit| instead
>>>>>>>>                 of |QTextEdit| as is is more performant with
>>>>>>>>                 high amounts of text.
>>>>>>>>
>>>>>>>>                 If you are interested, I just wrote an
>>>>>>>>                 asynchronous module for PySide for the project
>>>>>>>>                 on which I am currently working. It is based on
>>>>>>>>                 Python’s futures
>>>>>>>>                 <http://pythonhosted.org/futures/> module and
>>>>>>>>                 works great with Qt’s signals/slots. Although
>>>>>>>>                 the project is primarily closed-source, I would
>>>>>>>>                 be happy to share the async implementation with
>>>>>>>>                 you. I don’t know if would fit your needs, but
>>>>>>>>                 for us it’s much easier than manually spawning
>>>>>>>>                 |QThread|s and even easier than |QThreadPool|.
>>>>>>>>
>>>>>>>>                 Good luck!
>>>>>>>>
>>>>>>>>                     I will investigate that now
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                     On 24/01/14 16:08, Sean Fisk wrote:
>>>>>>>>>                     On Thu, Jan 23, 2014 at 9:42 PM, Frank
>>>>>>>>>                     Rueter | OHUfx <frank at ohufx.com
>>>>>>>>>                     <mailto:frank at ohufx.com>> wrote:
>>>>>>>>>
>>>>>>>>>                         Thanks Sean and Ryan,
>>>>>>>>>
>>>>>>>>>                         I'm still not quite clear on how this
>>>>>>>>>                         ties into QProcess.start()
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                     It doesn’t tie in with |QProcess| at all.
>>>>>>>>>                     We’re advising to avoid using that :)
>>>>>>>>>
>>>>>>>>>                         I do have a if __name__ ... block in
>>>>>>>>>                         the script in question.
>>>>>>>>>                         An example would certainly be awesome,
>>>>>>>>>                         but if it's less hassle, explaining
>>>>>>>>>                         how your and Ryan's advise helps use
>>>>>>>>>                         QProcess on a python module might
>>>>>>>>>                         already suffice. Maybe a simlpe
>>>>>>>>>                         example says it all though?!
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                     I will whip up a simple example for you,
>>>>>>>>>                     but it might take a few hours (lots of
>>>>>>>>>                     stuff to do right now).
>>>>>>>>>
>>>>>>>>>                         I'm not using python 3 btw
>>>>>>>>>
>>>>>>>>>                         Thanks guys for your help!!
>>>>>>>>>
>>>>>>>>>                         frank
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                         On 24/01/14 15:33, Sean Fisk wrote:
>>>>>>>>>>
>>>>>>>>>>                         Hi Frank,
>>>>>>>>>>
>>>>>>>>>>                         You should definitely avoid calling
>>>>>>>>>>                         Python as a subprocess if you can. As
>>>>>>>>>>                         far as Ryan’s example, I agree with
>>>>>>>>>>                         the |if __name__...| but I think that
>>>>>>>>>>                         using the |imp| module is a bit
>>>>>>>>>>                         overkill. I would recommend using
>>>>>>>>>>                         Setuptool’s |entry_points| keyword
>>>>>>>>>>                         <http://pythonhosted.org/setuptools/setuptools.html#automatic-script-creation>.
>>>>>>>>>>                         Or distutils’ |scripts| keyword
>>>>>>>>>>                         <http://docs.python.org/2/distutils/setupscript.html#installing-scripts>,
>>>>>>>>>>                         if you must.
>>>>>>>>>>
>>>>>>>>>>                         An example of a well-known Python
>>>>>>>>>>                         package which does this is Pygments
>>>>>>>>>>                         <https://bitbucket.org/birkenfeld/pygments-main>,
>>>>>>>>>>                         which has a large “library” component
>>>>>>>>>>                         but also comes with the |pygmentize|
>>>>>>>>>>                         command-line script. The Pygments
>>>>>>>>>>                         codebase is pretty large, so if you
>>>>>>>>>>                         would like me to whip up a simpler
>>>>>>>>>>                         example I’d be glad to do so.
>>>>>>>>>>
>>>>>>>>>>                         Cheers,
>>>>>>>>>>
>>>>>>>>>>                         --
>>>>>>>>>>                         Sean Fisk
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                         On Thu, Jan 23, 2014 at 9:17 PM,
>>>>>>>>>>                         Frank Rueter | OHUfx <frank at ohufx.com
>>>>>>>>>>                         <mailto:frank at ohufx.com>> wrote:
>>>>>>>>>>
>>>>>>>>>>                             Sorry if I'm being thick, but I'm
>>>>>>>>>>                             not quite understanding how this
>>>>>>>>>>                             helps to connect a python
>>>>>>>>>>                             function to qprocess?! All your
>>>>>>>>>>                             code does is execute the script,
>>>>>>>>>>                             right?!
>>>>>>>>>>                             I can already call
>>>>>>>>>>                             myscript.main() straight up, but
>>>>>>>>>>                             maybe I'm missing the point as
>>>>>>>>>>                             I'm unfamiliar with the imp module.
>>>>>>>>>>
>>>>>>>>>>                             Let me elaborate a little bit more:
>>>>>>>>>>                             myscript.main() calls a bunch of
>>>>>>>>>>                             other python scripts that
>>>>>>>>>>                             (directly or through other
>>>>>>>>>>                             scripts again) execute external
>>>>>>>>>>                             programs to do some conversion
>>>>>>>>>>                             work. Those external programs
>>>>>>>>>>                             spit out their progress to stdout
>>>>>>>>>>                             which I can see fine when I run
>>>>>>>>>>                             myscript.main() manually in a
>>>>>>>>>>                             python terminal.
>>>>>>>>>>
>>>>>>>>>>                             Now I need run myscript.main()
>>>>>>>>>>                             via QProcess and grab stdout to
>>>>>>>>>>                             do be able to show a progress bar
>>>>>>>>>>                             as well as show stdout and stderr
>>>>>>>>>>                             in a debug window inside my QT code.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                             Cheers,
>>>>>>>>>>                             frank
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                             On 24/01/14 14:58, Ryan Gonzalez
>>>>>>>>>>                             wrote:
>>>>>>>>>>>                             If you put an "if __name__ ==
>>>>>>>>>>>                             '__main__'" and a main
>>>>>>>>>>>                             functions, you could always
>>>>>>>>>>>                             import the script from the GUI
>>>>>>>>>>>                             frontend. Example:
>>>>>>>>>>>
>>>>>>>>>>>                             myscript.py
>>>>>>>>>>>
>>>>>>>>>>>                             def main(argv):
>>>>>>>>>>>                             do_cool_stuff()
>>>>>>>>>>>                                 return 0
>>>>>>>>>>>
>>>>>>>>>>>                             if __name__ == '__main__':
>>>>>>>>>>>                             sys.exit(main(sys.argv))
>>>>>>>>>>>
>>>>>>>>>>>                             mygui.py(Python 2):
>>>>>>>>>>>
>>>>>>>>>>>                             import imp
>>>>>>>>>>>
>>>>>>>>>>>                             ...
>>>>>>>>>>>
>>>>>>>>>>>                             main =
>>>>>>>>>>>                             imp.load_module('myscript',
>>>>>>>>>>>                             *imp.find_module('myscript'))
>>>>>>>>>>>
>>>>>>>>>>>                             main.main(my_argv)
>>>>>>>>>>>
>>>>>>>>>>>                             mygui.py(Python 3):
>>>>>>>>>>>
>>>>>>>>>>>                             import importlib.machinery
>>>>>>>>>>>
>>>>>>>>>>>                             main =
>>>>>>>>>>>                             importlib.machinery.SourceFileLoader('myscript',
>>>>>>>>>>>                             'myscript.py').load_module('myscript')
>>>>>>>>>>>
>>>>>>>>>>>                             main.main(my_argv)
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>                             On Thu, Jan 23, 2014 at 7:48 PM,
>>>>>>>>>>>                             Frank Rueter | OHUfx
>>>>>>>>>>>                             <frank at ohufx.com
>>>>>>>>>>>                             <mailto:frank at ohufx.com>> wrote:
>>>>>>>>>>>
>>>>>>>>>>>                                 Hi all,
>>>>>>>>>>>
>>>>>>>>>>>                                 I got a little code design
>>>>>>>>>>>                                 question:
>>>>>>>>>>>
>>>>>>>>>>>                                 I have a python script that
>>>>>>>>>>>                                 does a lot of file
>>>>>>>>>>>                                 processing/converting/uploading
>>>>>>>>>>>                                 etc and I'd like to write a
>>>>>>>>>>>                                 decent
>>>>>>>>>>>                                 interface for it now.
>>>>>>>>>>>                                 The main goal is to be able
>>>>>>>>>>>                                 to show the user detailed
>>>>>>>>>>>                                 info about the
>>>>>>>>>>>                                 current step and progress as
>>>>>>>>>>>                                 well as clean up properly in
>>>>>>>>>>>                                 case the whole
>>>>>>>>>>>                                 thing is cancelled.
>>>>>>>>>>>
>>>>>>>>>>>                                 My existing python code
>>>>>>>>>>>                                 needs to stay independent of
>>>>>>>>>>>                                 QT so any
>>>>>>>>>>>                                 application that supports
>>>>>>>>>>>                                 python can use it.
>>>>>>>>>>>                                 I am wondering now how to
>>>>>>>>>>>                                 best connect the python
>>>>>>>>>>>                                 script and the PySide
>>>>>>>>>>>                                 code. Should I just run the
>>>>>>>>>>>                                 script as an argument to the
>>>>>>>>>>>                                 python
>>>>>>>>>>>                                 interpreter like I would
>>>>>>>>>>>                                 with any other program? E.g.:
>>>>>>>>>>>
>>>>>>>>>>>                                 process = QtCore.QProcess(self)
>>>>>>>>>>>                                 process.start(<path_to_python>,
>>>>>>>>>>>                                 <path_to_python_script>)
>>>>>>>>>>>
>>>>>>>>>>>                                 As simple as this seems, it
>>>>>>>>>>>                                 feels odd to use python to
>>>>>>>>>>>                                 call itself as an
>>>>>>>>>>>                                 external program.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>                                 I'm happy to go that way but
>>>>>>>>>>>                                 am curious how others are
>>>>>>>>>>>                                 doing this?!
>>>>>>>>>>>
>>>>>>>>>>>                                 Cheers,
>>>>>>>>>>>                                 frank
>>>>>>>>>>>
>>>>>>>>>>>                                 _______________________________________________
>>>>>>>>>>>                                 PySide mailing list
>>>>>>>>>>>                                 PySide at qt-project.org
>>>>>>>>>>>                                 <mailto:PySide at qt-project.org>
>>>>>>>>>>>                                 http://lists.qt-project.org/mailman/listinfo/pyside
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>                             -- 
>>>>>>>>>>>                             Ryan
>>>>>>>>>>>                             If anybody ever asks me why I
>>>>>>>>>>>                             prefer C++ to C, my answer will
>>>>>>>>>>>                             be simple: "It's
>>>>>>>>>>>                             becauseslejfp23(@#Q*(E*EIdc-SEGFAULT.
>>>>>>>>>>>                             Wait, I don't think that was
>>>>>>>>>>>                             nul-terminated."
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                             _______________________________________________
>>>>>>>>>>                             PySide mailing list
>>>>>>>>>>                             PySide at qt-project.org
>>>>>>>>>>                             <mailto:PySide at qt-project.org>
>>>>>>>>>>                             http://lists.qt-project.org/mailman/listinfo/pyside
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                 _______________________________________________
>>>>>>>                 PySide mailing list
>>>>>>>                 PySide at qt-project.org  <mailto:PySide at qt-project.org>
>>>>>>>                 http://lists.qt-project.org/mailman/listinfo/pyside
>>>>>>
>>>>>>
>>>>>>
>>>>>>                 _______________________________________________
>>>>>>                 PySide mailing list
>>>>>>                 PySide at qt-project.org  <mailto:PySide at qt-project.org>
>>>>>>                 http://lists.qt-project.org/mailman/listinfo/pyside
>>>>>
>>>>>
>>>>>                 _______________________________________________
>>>>>                 PySide mailing list
>>>>>                 PySide at qt-project.org <mailto:PySide at qt-project.org>
>>>>>                 http://lists.qt-project.org/mailman/listinfo/pyside
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>         -- 
>>>         ohufxLogo 50x50 <http://www.ohufx.com> 	*vfx compositing
>>>         <http://ohufx.com/index.php/vfx-compositing> | *workflow
>>>         customisation and consulting
>>>         <http://ohufx.com/index.php/vfx-customising>* *
>>>
>>>
>>>
>>>         _______________________________________________
>>>         PySide mailing list
>>>         PySide at qt-project.org  <mailto:PySide at qt-project.org>
>>>         http://lists.qt-project.org/mailman/listinfo/pyside
>>
>>         -- 
>>         ohufxLogo 50x50 <http://www.ohufx.com> 	*vfx compositing
>>         <http://ohufx.com/index.php/vfx-compositing> | *workflow
>>         customisation and consulting
>>         <http://ohufx.com/index.php/vfx-customising>* *
>>
>>
>>         _______________________________________________
>>         PySide mailing list
>>         PySide at qt-project.org <mailto:PySide at qt-project.org>
>>         http://lists.qt-project.org/mailman/listinfo/pyside
>>
>>
>
>     -- 
>     ohufxLogo 50x50 <http://www.ohufx.com> 	*vfx compositing
>     <http://ohufx.com/index.php/vfx-compositing> | *workflow
>     customisation and consulting
>     <http://ohufx.com/index.php/vfx-customising>* *
>
>

-- 
ohufxLogo 50x50 <http://www.ohufx.com> 	*vfx compositing 
<http://ohufx.com/index.php/vfx-compositing> | *workflow customisation 
and consulting <http://ohufx.com/index.php/vfx-customising>* *

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20150723/e622f463/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/png
Size: 2666 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20150723/e622f463/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/png
Size: 2666 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20150723/e622f463/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/png
Size: 2666 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20150723/e622f463/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ohufxLogo_50x50.png
Type: image/png
Size: 2666 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20150723/e622f463/attachment-0003.png>


More information about the PySide mailing list