#
# Using PyGTK with Stackless
#
# Authors: Richard Tew (extended and documented)
# Sebastian de Bellefon (added Stackless scheduling support)
# PyGTK Tutorial, Chapter 2 / Getting Started
#
# This example is intended to illustrate how to get the PyGTK framework
# main loop to work with the Stackless framework main loop. It shows
# that as the GTK main loop waits for events for the created window,
# Stackless continues scheduling in the background.
#
# This code was written to serve as an example of Stackless Python usage.
# Feel free to email me with any questions, comments, or suggestions for
# improvement.
#
# But a better place to discuss Stackless Python related matters is the
# mailing list:
#
# http://www.tismer.com/mailman/listinfo/stackless
#
import stackless
import gobject
import gtk
import weakref
class HelloWorld:
def hello(self, widget, data=None):
global cnt
print "There have been", cnt, "schedulings of the other tasklet while you were sitting there!"
cnt = 0
def schedule (self):
gobject.timeout_add(50, self.schedule)
stackless.schedule()
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event", self.delete_event)
self.window.set_border_width(10)
self.button = gtk.Button("Hello World")
self.button.connect("clicked", self.hello, None)
self.window.add(self.button)
self.button.show()
self.window.show()
### Here is the trick
gobject.timeout_add(50, self.schedule)
def main(self):
print 'main'
t = stackless.tasklet(gtk.main)()
# Keep a reference to this tasklet, but only a weakref. We can use this
# to kill it when the window is closed.
self.taskletRef = weakref.proxy(t)
def delete_event(self, widget, event, data=None):
"""
Called when the window gets a close event. Whether the close button is
clicked or something similar.
"""
print 'delete_event', widget, event, data
# We want to kill the gtk main function call. Perhaps there is a better way?
self.taskletRef.kill()
# Returning False gets the window closed.
return False
# A global variable to track the number of schedulings of the other tasklet
# while the user was doing nothing.
cnt = 0
def schedule_func():
"""
The other tasklet. This runs and increments a counter. What this is intended to
show is that the PyGTK main loop is giving the scheduler a chance to run.
"""
global cnt
while 1:
cnt += 1
stackless.schedule()
if __name__ == "__main__":
# Start the scheduling proof tasklet.
stackless.tasklet(schedule_func)()
# Create the Window and schedule the GTK main loop.
hw = HelloWorld()
hw.main()
# Run the scheduler. As you know, this will run until there are not tasklets
# left still scheduled.
print 'calling stackless.run'
stackless.run()
# The user must have closed the window.
print 'done'