1

Let me introduce the goal of the application I'm building: I am creating a front-end GUI using PySide (Qt) for a fortran based application used in the framework of CFD. The fortran application is compiled as a *.exe file, and, when executed, it continuously provides the simulated lapse of time and other output details (when I launch it from the console, these data continously appear until it finishes).

For example, if I executed the external code from the console I would get

>> myCFDapplication.exe
   Initializing...
   Simulation start...
   Time is 0.2
   Time is 0.4
   Time is 0.6
   Time is 0.8
   Time is 1.0
   Simulation finished
>>

With quite a long lapse of time between "Time is .." and the next line.

The objective of the GUI is to generate the initialization files for the external application, to launch the external application and finally to provide the user the computation output information in real time (as plane text). From other similar topics in this site, I have been able to launch my external application from Python using the following code

import os, sys
import subprocess

procExe = subprocess.Popen("pru", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

while procExe.poll() is None:
line = procExe.stdout.readline()
print("Print:" + line)

but the output is only displayed when the execution finishes, and moreover, the whole GUI freezes until that moment.

I would like to know how to launch my external application using Python, getting the output in real time and passing it to the GUI instantaneously, if possible. The idea would be to print the output in different lines inside a "TextEdit" dialog using the function "append(each_output_line)".

Adr
  • 11
  • 1
  • 4
  • Don't know whether this will work in your particular case, but try running the process *after* the application's event loop has started, and then periodically call `qApp.processEvents()` inside the polling loop. – ekhumoro Sep 30 '15 at 14:06
  • Thanks for your answer! Anyway, I do not manage to make it work by using `QCoreApplication.processevent()`. I have included it in the following way inside my function `def startSimulation(self): procExe = subprocess.Popen("pru", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) while procExe.poll() is None: QCoreApplication.processEvents() line = procExe.stdout.readline() self.console.append(line)` Did you mean so? – Adr Sep 30 '15 at 14:35
  • I assume that "do not manage to make it work" means that it still blocks? If so, you will probably have to move the processing to a separate thread and then emit a custom signal from the thread whenever there is new output (there are dozens of questions on SO that show how to do that in PyQt/PySide). However, there is no guarantee that that will work, either - in which case, you will need to try [multiprocessing](https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing). – ekhumoro Sep 30 '15 at 15:27
  • Yes, it is still blocking. Thanks, I will read on that... as you see, I am new in this and I am still getting to know python and GUI programming. – Adr Sep 30 '15 at 18:39

1 Answers1

0

Check out Non-blocking read on a subprocess.PIPE in python and look at the use of Queues to do a non-blocking read of the subprocess. The biggest change for your Qt application is that you are probably going to have to use multiprocessing since, as you have observed, anything blocking in your application is going to freeze the GUI.

Community
  • 1
  • 1
sid16rgt
  • 736
  • 5
  • 14