Suspending Code Execution After Call to Draw.Register

I’m trying to find out how to write a program with code that will not be executed until after a call to Draw.Exit. Here’s the sample:


#!BPY

from Blender import Draw

def main():
    print "In main() BEFORE call to Draw.Register()"
    Draw.Register(gui,event,bevent)
    print "In main() AFTER call to Draw.Register()"

def gui():
    print "INSIDE gui() after calling Draw.Register()"
    Draw.PushButton("Push Me",100,10,10,100,25)

def event(evt,val):
    if val:return
    if evt==Draw.ESCKEY:Draw.Exit()

def bevent(evt):
    if evt==100:Draw.Exit()

main()

Here’s the output from the program:


In main() BEFORE call to Draw.Register()
In main() AFTER call to Draw.Register()
INSIDE gui() after calling Draw.Register()

This is what I would like to see printed instead:


In main() BEFORE call to Draw.Register()
INSIDE gui() after calling Draw.Register()
In main() AFTER call to Draw.Register()

Anyone know how to get this done?

#!BPY

from Blender import Draw, Window

def main():
    print "In main() BEFORE call to Draw.Register()"
    Draw.Register(gui,event,bevent)
    Window.Redraw()
    print "In main() AFTER call to Draw.Register()"

def gui():
    print "INSIDE gui() after calling Draw.Register()"
    Draw.PushButton("Push Me",100,10,10,100,25)

def event(evt,val):
    if val:return
    if evt==Draw.ESCKEY:Draw.Exit()

def bevent(evt):
    if evt==100:Draw.Exit()

main()

So force a redraw, before you continue.
This gives:

In main() BEFORE call to Draw.Register()
INSIDE gui() after calling Draw.Register()
In main() AFTER call to Draw.Register()
INSIDE gui() after calling Draw.Register()

Close enough to what you want?
If you really want to you can probably get rid of the second “inside gui” by testing if it has already been run, but I don’t see any problem in leaving it there.

Thanks, but that kind of gets right to what I’m confused about. I want to be able to do some mesh and object work with user input from the gui and then call Redraw(-1). The problem is that the documentation says not to use Window.Redraw until after Draw.Exit has been called. Here’s the link: http://www.blender.org/documentation/246PythonDoc/Draw-module.html,
and the text: Inside the windowing loop (after Draw.Register() has been executed and before Draw.Exit() is called), don’t use the redraw functions from other modules (Blender and Window). The Draw submodule has its own Draw.Redraw() and Draw.Draw() functions that can be used inside the windowing loop.
Again Window.Redraw is the function that I want to be able to call, but don’t know how to do it until after exiting Draw.

To be honest, I’ve always ignored that message and never got in any trouble. Of course it’s better to follow the rules (the people who wrote that message know Blender way better than I do), so I suggest you use Draw.Draw() instead of Window.Redraw(). This gives the same result, but is in the Draw module.


#!BPY

from Blender import Draw

def main():
    print "In main() BEFORE call to Draw.Register()"
    Draw.Register(gui,event,bevent)
    Draw.Draw()
    print "In main() AFTER call to Draw.Register()"

def gui():
    print "INSIDE gui() after calling Draw.Register()"
    Draw.PushButton("Push Me",100,10,10,100,25)

def event(evt,val):
    if val:return
    if evt==Draw.ESCKEY:Draw.Exit()

def bevent(evt):
    if evt==100:Draw.Exit()

main()

If you’re interested in the way events are processed it might also be a good idea to play a bit with for example QRead() (in the Window module, so only for testing). Even better would of course be if some guru could enlighten us (even though this area will be thoroughly changed in 2.50).

I can’t seem to get the 3d window redrawn from within the script though. If I mouse around in the 3d window after script execution, the new object show up, but it doesn’t seem to be automatic.

Inside the windowing loop (after Draw.Register() has been executed and before Draw.Exit() is called), don’t use the redraw functions from other modules (Blender and Window). The Draw submodule has its own Draw.Redraw() and Draw.Draw() functions that can be used inside the windowing loop.

What this means is that to redraw the GUI(Your python GUI) you should use the Draw.Redraw() and Draw.Draw() functions and not the Window.Redraw() function like this Window.Redraw(Window.Types[‘SCRIPT’]).
That how i understand it. So it should be safe to use Window.Redraw() to update the 3dview.

Note that there are other functions you might need to call to update the mesh.

Here’s the thread with the script. I disabled the call to main, and just using the gui registration:
http://blenderartists.org/forum/showthread.php?t=140452

I think foom is correct in saying that the remark in the api about not using Window and Blender redraw is only about the script window.
The Draw module simply doesn’t have access to the 3D view in your setup. So I think adding Window.Redraw() (-1 isn’t needed, only the 3D view needs to be updated) at line 663 is allowed in this case and should solve your problem.