I'm making a simple wxPython app on win32 that does a number of calls to external binaries. Everything works fine, except the GUI doesn't update well while the external process is running. This makes for an ugly window and non-updated status StaticTexts, so I'd like to fix it. Window . Update () helps some, but it still doesn't do the job. I've also tried Window . Refresh () and Window . UpdateWindowUI () and every combination of the three, but no luck. Any thoughts?

# Call process
Process = subprocess . Popen ( Command_Line )
# Wait on process to complete
while Process . poll () == None :
	# Update GUI
	Window . Update ()
	# Wait a bit, don't hog the CPU
	time . sleep ( 0.25 )

Recommended Answers

All 5 Replies

You'll need to use threading to handle this. One thread calls the function which does the subprocess, and the other calls a function which updates the GUI. Something along the lines of:

# untested!
import thread
from time import sleep

def myFunc():
    while True:
        print 'Hello world!'
        sleep(1)
def func2():
    while True:
       print '#2!'
       sleep(0.5)

thread.start_new_thread(myFunc, ())
thread.start_new_thread(func2, ())

It's started running the myFunc function's endless loop and func2's stuff while it can continue on with other things in the script. Check this for more info:

http://docs.python.org/library/thread.html

Also, please don't use such bad writing style in your code. Only put spaces between non-unary operators. Or, at least don't put spaces between the periods denoting namespaces (like "time . sleep(0.25)") and the colons in your conditional statements. You can check here for a style guide for Python.

Thanks for the suggestion!

I needed a way to wait on the thread to complete before continuing, so I wound up using threading instead. However, it's still not updating the window well.

import subprocess
import threading
import time

class Thread ( threading . Thread ):
	def run ( Self ):
		subprocess . call ( "mycommand.exe" )

External_Executable = Thread ()
External_Executable . start ()

while External_Executable . is_alive ():
	Window . Update ()
	time . sleep ( 0.25 )

With this setup, it's acting just the way it did before. I'd appreciate any more feedback anyone might have.

Thanks!


P.S. My coding style is on purpose. I put great emphasis on human readability, which comes out in many ways, including generous whitespace.

I'd put the window updating segment in a function and call that via a thread as well. Try how that works out.

P.S. As long as your style works for you. I personally can't stand it as whitespace is good, but too much is difficult. It just makes it hard to see some of the OOP-based concepts with the periods being so spaced out.

Your code has a couple of issues, if i am not wrong it will not actually start using threading with your code as it is. You need to add a couple of lines

class Thread ( threading . Thread ):
        def __init__(self):
            threading.Thread.__init__(self)

	def run ( Self ):
		subprocess . call ( "mycommand.exe" )

See how i have called the __init__ method on the threading.Thread class? This means that now it will run the __init__ method of the Thread class, which is needed for threading to work properly with classes.

So try replacing you current class with that and try again and see how it all goes :)

Hope that helps

commented: Ah, good point. I missed that! :D +4

Well, based on the replies here, I just spent the last two days teaching myself the multiprocessing module (with inter-process queues) so I could put the UI in one process and the workload in another to solve this problem.

I was pretty much done with that when DevCoach at Dev Shed offered this: instead of Window . Update (), use wx . Yield ().

It works perfectly. :)

Well, at least I know how to multi-process now! LOL

Thanks, all!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.