stop without exiting?

1372 views
Skip to first unread message

Timothy Lillicrap

unread,
Mar 6, 2012, 10:18:23 AM3/6/12
to glumpy-users
Hi There,

I'm trying to figure out a way to use a glumpy figure, then once i've
had the user interact with it, i want to carry on with some regular
python code. At the moment, every time I try to get rid of the glumpy
figure, the whole process dies.

I saw the old post about using window.exit() but this doesn't seem to
work for me. I've included a basic example at the end where, if the
user presses 'q' the program would ideally carry on and execute the
code after fig.show().

Is there an easy fix for this?

Tim.

ps, Once again, thank you for the ongoing help. In case you're
interested, I thought I'd write to tell you briefly what I'm trying to
do with glumpy. I work in a neuroscience lab in the Pharmacology
Dept. at Oxford. We collect a lot of image data of neural activity on
microscopes (using 2photon calcium imaging). I'm building tools to
register these images to counter small movements of the tissue/
microscope. There are of course automated tools for image
registration/alignment, but we have found these to be generally
inferior to good manual alignments. At the moment even the tools for
manual alignment are quite crude though, and I'm hoping to make a much
better interface for users. I'm hoping to eventually release the
software on an open license for other neuroscience labs to use.


################################################################
################################################################

import numpy, glumpy
import Image
import pdb
import numpy as np
import OpenGL
import OpenGL.GL as gl
import OpenGL.GLU as glu
import OpenGL.GLUT as glut

refimg = np.random.uniform(0,1, (512,512,2)).astype(np.float32)

img = np.ones((100,100,4)).astype(np.float32)
img *= (0,0,1.,.5)

fig = glumpy.figure( (512,512) )
grefimg = glumpy.Image(refimg)
image = glumpy.Image(img)
image.x = 0.
image.y = 0.
grefimg.x = 0.
grefimg.y = 0.

@fig.event
def on_init():
print 'Inititalization'

@fig.event
def on_draw():
print 'Drawing requested'
fig.clear()
gl.glEnable( gl.GL_BLEND )
gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA )

grefimg.update()
grefimg.draw(grefimg.x,grefimg.y,
0.,width=fig.width,height=fig.height)

image.draw(image.x,image.y,0.,width=fig.width/2.,height=fig.height/
2.)


@fig.event
def on_mouse_motion(x, y, dx, dy):
print 'Mouse motion (x=%.1f, y=%.1f, dx=%.1f, dy=%.1f)' % (x,y,dx,dy)

@fig.event
def on_mouse_drag(x, y, dx, dy, button):
print 'Mouse drag (x=%.1f, y=%.1f, dx=%.1f, dy=%.1f, button=%d)' %
(x,y,dx,dy,button)
image.x = image.x + dx
image.y = image.y + dy
fig.redraw()

@fig.event
def on_key_release(symbol, modifiers):
print 'Key released (symbol=%s, modifiers=%s)'% (symbol,modifiers)

if (symbol == 113):
print 'user exit requested...'
fig.window.hide()
fig.window.stop()
# fig.window.exit()

fig.show()

print 'the program continued as desired...'

Nicolas Rougier

unread,
Mar 7, 2012, 3:06:33 AM3/7/12
to glumpy-users


Maybe the following code may help you:
Note that the glutCheckLoop will block, waiting for the next event.


import sys
import OpenGL.GL as gl
import OpenGL.GLUT as glut

stop = False

def display():
gl.glClear (gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
glut.glutSwapBuffers()

def close():
global stop
print 'Window has been closed'
stop=True

glut.glutInit(sys.argv)
glut.glutInitDisplayMode(glut.GLUT_DOUBLE |
glut.GLUT_RGBA |
glut.GLUT_DEPTH)
glut.glutCreateWindow(sys.argv[0])
glut.glutDisplayFunc(display)
glut.glutWMCloseFunc(close)
gl.glClearColor(1,1,1,1)

while not stop:
glut.glutCheckLoop()


Nicolas


On Mar 6, 4:18 pm, Timothy Lillicrap <timothy.lillic...@gmail.com>
wrote:

Timothy Lillicrap

unread,
Mar 7, 2012, 8:18:23 AM3/7/12
to glumpy-users
Strange, my glut doesn't seem to have this function. I get:

AttributeError: 'module' object has no attribute 'glutCheckLoop'

When I try to run this code. I have a pretty standard install of
Ubuntu running. And here is what
I get when I inspect the glut module directly I see:

glut
Out[18]: <module 'OpenGL.GLUT' from '/usr/lib/pymodules/python2.7/
OpenGL/GLUT/__init__.pyc'>
glut.__package__
Out[19]: 'OpenGL.GLUT'

And it definitely doesn't have the glutCheckLoop() function.

I have:
freeglut3
&
python-opengl

installed.

Any idea why my glut doesn't seem to have this function?

Tim

Nicolas Rougier

unread,
Mar 7, 2012, 8:26:28 AM3/7/12
to glumpy-users


Oops, sorry I thought you were on OSX.
If you"re on Ubuntu, the freeglut implementation should have the
glut.glutLeaveMainLoop().
Can you check it ?

Nicolas



On Mar 7, 2:18 pm, Timothy Lillicrap <timothy.lillic...@gmail.com>

Timothy Lillicrap

unread,
Mar 7, 2012, 8:40:21 AM3/7/12
to glumpy-users
Yep I've got that function.

Can I just call that function, say in my example above at the
key_release event?
That is, right in:
if (symbol == 113):
print 'user exit requested...'
HERE?

Nicolas Rougier

unread,
Mar 7, 2012, 8:45:08 AM3/7/12
to glumpy...@googlegroups.com

Well, the window stop function is defined as:

def stop(self):
'''Exit mainloop'''
if (glut.glutLeaveMainLoop):
glut.glutLeaveMainLoop()
else:
raise RuntimeError(
'''Your GLUT implementation does not allow to stops the main loop''')


glut.glutLeaveMainLoop may exist but it should also point to the actual function (hence the test).
I suspect yours is empty and so glumpy raise the error.

Try:

>>> import OpenGL.GLUT as glut
>>> bool(glut.glutLeaveMainLoop)

It should give you True but I suspect you'll get False.


What is your glut implementation, do you know ?

Timothy Lillicrap

unread,
Mar 7, 2012, 8:45:52 AM3/7/12
to glumpy-users
Hmmm, my simple strategy of just calling glut.glutLeaveMainLoop()
doesn't quite seem to work. it still seems that this will kill the
program rather than allowing it to continue on after the
fig.window.start().

Tim.

On Mar 7, 1:40 pm, Timothy Lillicrap <timothy.lillic...@gmail.com>

Timothy Lillicrap

unread,
Mar 7, 2012, 8:49:24 AM3/7/12
to glumpy-users
Ok, I get:

import OpenGL.GLUT as glut
In [2]: bool(glut.glutLeaveMainLoop)
Out[2]: True

And my glut is freeglut3 I believe.

Tim.

Nicolas Rougier

unread,
Mar 7, 2012, 9:00:03 AM3/7/12
to glumpy-users

From freeglut documentation maybe a :

glut.glutSetOption(glut.GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_CONTINUE_EXECUTION)

will do the trick (I'm on osx, I cannot test easily).


Nicolas


On Mar 7, 2:49 pm, Timothy Lillicrap <timothy.lillic...@gmail.com>

Timothy Lillicrap

unread,
Mar 7, 2012, 9:06:17 AM3/7/12
to glumpy-users
Will try this. Thanks. I found this bit in the free glut
documentation too, which looks like it might be a hint. It explains
exactly the problem I have too:

"3.4.1 glutMainLoop Behaviour
One of the commonest complaints about the GLUT library was that once
an application called glutMainLoop, it never got control back. There
was no way for an application to loop in GLUT for a while, possibly as
a subloop while a specific window was open, and then return to the
calling function. A new function, glutMainLoopEvent, has been added to
allow this functionality. Another function, glutLeaveMainLoop, has
also been added to allow the application to tell freeglut to clean up
and close down. "

So maybe I can try using glutMainLoopEvent if your suggestion doesn't
work.

Tim.

Timothy Lillicrap

unread,
Mar 7, 2012, 9:16:55 AM3/7/12
to glumpy-users
Finally found a solution similar to what you suggested. On my system
(Ubuntu 11.10 with recent packages) anyway you seem to need both of
these lines:

glut.glutSetOption(glut.GLUT_ACTION_ON_WINDOW_CLOSE,
glut.GLUT_ACTION_CONTINUE_EXECUTION)
glut.glutSetOption(glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS,
glut.GLUT_ACTION_CONTINUE_EXECUTION)

Neither one of these works on their own for me. You need both.

Tim.

Timothy Lillicrap

unread,
Mar 7, 2012, 10:32:59 AM3/7/12
to glumpy-users
Unfortunately, with the solution I found below, you can exit the
glutMainLoop(), but you can't resume it.

It seems best to use a setup like you initially suggested but with:

while not stop:
glut.glutMainLoopEvent()

This setup lets you stop and resume with Freeglut.

Tim.


On Mar 7, 2:16 pm, Timothy Lillicrap <timothy.lillic...@gmail.com>

Will

unread,
Apr 14, 2012, 2:33:05 PM4/14/12
to glumpy...@googlegroups.com
Hi Nicolas, 

I was able to implement this code block with glut.glutCheckLoop() in order to exit glut without terminating Python.  I have tried implementing a glutWMCloseFunction in glumpy's glut backend by adding a _close function and a case in the stop function (see below), which closes the window but also kills python with a "Python quit unexpectedly." error pop up.  How could I go about implementing this function into the glumpy backend (without using glut?   

    def _close(self):
        glut.glutDestroyWindow(glut.glutGetWindow())

    def stop(self):
        '''Exit mainloop'''
        if (glut.glutLeaveMainLoop):
            glut.glutLeaveMainLoop()
        elif (glut.glutWMCloseFunc):
            glut.glutWMCloseFunc(self._close)
        else:
            raise RuntimeError(
                '''Your GLUT implementation does not allow to stops the main loop''')  

Best Regards, 
_Will

Nicolas Rougier

unread,
Apr 20, 2012, 11:17:28 AM4/20/12
to glumpy...@googlegroups.com

Hi Will,

Sorry for the late answer.
Do you have a complete (small) code such that I can test it on my side ?

Nicolas

Will

unread,
Apr 20, 2012, 1:05:15 PM4/20/12
to glumpy...@googlegroups.com
Hi Nicolas, 

Thanks for the reply.  Basically, like Timothy, I want to be able to exit the glut main loop using the existing glumpy glut backend.  Unlike Timothy, I do not need to restart glut main loop after exiting, but just want to keep the current python process alive.  I am running Mac OSX 10.7.3. using the latest PyOpenGL (version 3.0.2a5).  Before discussing any example code I wanted to go over some limitations I have encountered with PyOpenGL.  I have tried importing some of the glut functions listed above with the following results:

>>> bool(glut.glutLeaveMainLoop)
False
>>> bool(glut.glutSetOption)
False
>>> bool(glut.glutWMCloseFunc)
True
>>> bool(glut.glutCheckLoop)
True

This output leads me to wonder, if you are also developing on a Mac, what version of PyOpenGL are you using?  Also, I have noticed that you have included a comment in your recent release of the backend_glut.py that links to https://github.com/nanoant/osxglutIs it necessary to install this fork in order to have access the the above functions or is this only related to scrolling events.  Would you mind sharing your OpenGL setup on the Mac so that I might be able to access the glut.LeaveMainLoop function?  Or does this simply not work on Mac using pyopengl?  

The example you listed as the first response in this thread works for me, but I don't know how to incorporate that with glumpy.  Perhaps you could suggest a way to do this?  I will repost your example here for the purpose of clarity.  

stop = False 

def main():
def display(): 
gl.glClear (gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 
glut.glutSwapBuffers() 

def close(): 
global stop 
print 'Window has been closed' 
stop=True 

glut.glutInit(sys.argv) 
glut.glutInitDisplayMode(glut.GLUT_DOUBLE | 
                        glut.GLUT_RGBA   | 
                        glut.GLUT_DEPTH) 
glut.glutCreateWindow(sys.argv[0]) 
glut.glutDisplayFunc(display) 
glut.glutWMCloseFunc(close) 
gl.glClearColor(0.5,1,1,1) 

while not stop: 
   glut.glutCheckLoop() 


if __name__ == '__main__':
main()
print "Continued after exiting glut loop"

The above works, and executes the print line after exiting the main loop, which is the behavior that I am looking for (i.e. not sys.exit), so that I can continue to run the python thread after exiting glumpy.  However, I would prefer to use the glumpy backend if possible.

Thanks, 
_Will    

Nicolas Rougier

unread,
Jun 26, 2012, 3:18:27 AM6/26/12
to glumpy...@googlegroups.com

Sorry for the long long delay...
I've added a close event and a stoppable event loop (check the exit.py in the demos directory). Hopefully, it should solve your problem.


Nicolas

Will

unread,
Aug 11, 2012, 10:18:41 PM8/11/12
to glumpy...@googlegroups.com
Nicolas, 

Thank you, the close event works perfectly.  Solves a lot of problems for our project!  We use glumpy extensively in our projects – it has been a joy to work with and follow its development.  If you have a chance, take a look at how we are using glumpy in our project: http://code.google.com/p/pupil/

Best Regards, 
Will 

Nicolas Rougier

unread,
Aug 17, 2012, 4:17:20 AM8/17/12
to glumpy...@googlegroups.com

That's cool.

I'm glad glumpy can help you for  your pupil software. Seems very professional tool. I guess I cannot test it without an eye-tracker ?

Nicolas
Reply all
Reply to author
Forward
0 new messages