Ok I have narrowed the problem down, and I'm hoping somebody knows the solution. Basically I have a pyGTK application, using widgets and all of that. I have stripped all of the gtk objects out except the gtk.main() initializer. I basically want to start a threading process, and still have the main program run while the thread is executing. I have this working only when I have commented out gtk.main(). Try my example code below on your computer as is.

#!/usr/bin/env python

import threading, os

try:
	import gtk
  	import gtk.glade
except:
	sys.exit(1)

class CommandOutput(threading.Thread):
    def __init__(self, command):
        threading.Thread.__init__(self)        
        self.command = command
    def run(self):
        os.system(self.command)
        print 'Finished background process, should always be printed last.'

class Caller:
	def __init__(self):
		background = CommandOutput("ls -la /")
		background.start()
		print 'The main program continues to run in foreground. This should be the first thing printed.'
		
if __name__ == "__main__":
	objCaller = Caller()
	#gtk.main()

So if you run this in commandline python test.py it works as expected. However My program requires gtk widgets and objects. so if you Uncomment the last line there (#gtk.main()) and run the command, it waits after printing the one statement. It will Only proceed to execute background.start() when I press "Control + C" to terminate, and it then spews out the ls and then the final print statement.

Could it be because the gtk.main() is recursively ran once called? If so how can I avoid this.

Thanks for any help in advance

Recommended Answers

All 3 Replies

It will Only proceed to execute background.start() when I press "Control + C" to terminate, and it then spews out the ls and then the final print statement.

Can you run the thread from GTK, say when someone presses a button? Obviously GTK's locks prevent what you are doing. Running it in the background works if that helps. There are probably solutions on the GTK boards as well.

if __name__ == "__main__":
	#objCaller = Caller()
        print "Tag 1", datetime.datetime.now()
        os.system( "ls &")
        print "Tag 2", datetime.datetime.now()
        gtk.main()

Somebody told me they had a similar problem with wxPython. They solved it by using an internal Event loop included in the wx framework. I'm just now looking into gtk, glib and it appears there are some internal event loops but I'm having trouble understanding them. So I'm still open to suggestions.

woooee

And Yes I can run the thread from within an actual GTK window when I press a button, however it still ignores the threading aspect. meaning the output will be like

ls crap....
Finished background process, should always be printed last.
The main program continues to run in foreground. This should be the first thing printed.

Which means it still isn't executing the the thread properly. So for the sake of making this easy to understand i didn't bother including the widget and button because thats not where the problem is originating from.

Add gtk.gdk.threads_init()
in CommandOutput.__init__()

(this makes gdk not lock the whole process)

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.