That thread was started back in the days of Python 2, so some of the answers may not work in Python 3. I can’t test that as I don’t use Windows. Also, beware of the security risks when using shell=True.
Side note: you omitted the call to self.CreateStatusBar() in your example.
Didn’t try it with python, but there was an API call under windowses (I think shellExecute), where you could pass ‘HID’ as one of parameters, so while you’d still have a console window, it wouldn’t show.
Don’t know how would that translate into the .Popen() call, and does it use the same call in the first place.
My app, RIDE, is started on Windows with pythonw.exe, so no CLI is started, but when running a test case execution, it creates the stdout/stderr, which makes a momentary opening of a CLI window. This way the output of the command robot is captured.
Maybe you can get the idea by exploring RIDE and its source. In particular, the code at contrib/testrunner. Note, I did not created that code, it was a nice contribution by a user.
As it looks impossible 1) on Windows to 2) show live progress after 3) running an external CLI application 4) with no terminal window (“cmd”, “DOS box” in Windows-speak)… someone suggested a work-around: 1) Launch the app with no window (CREATE_NO_WINDOW)) and 2) Use a timer to read stdout:
from subprocess import Popen, PIPE, CREATE_NO_WINDOW
CMD = "ping -n 10 www.google.com"
class ListBoxFrame(wx.Frame):
def __init__(self, *args, **kwargs):
...
self.statusbar = self.CreateStatusBar()
self.dload_btn = wx.Button(panel, -1, "Download")
self.dload_btn.Bind(wx.EVT_BUTTON, self.OnDloadButtonClick)
self.update_timer = wx.Timer(self, 1)
self.Bind(wx.EVT_TIMER, self.update_status)
def OnDloadButtonClick(self,event):
self.process = Popen(CMD,stdout=PIPE,universal_newlines=True,creationflags=CREATE_NO_WINDOW)
self.update_timer.Start(100)
def update_status(self, event):
wx.Yield() #to keep the UI alive
if self.process.poll() is None:
# Process is still active.
line = self.process.stdout.readline()
if line:
self.statusbar.SetStatusText(line)
else:
# Process finished. Fetch remaining stdout.
for line in self.process.stdout.readlines():
self.statusbar.SetStatusText(line)
self.update_timer.Stop()
self.statusbar.SetStatusText("Done.")