Blender 3D: Noob to Pro/Advanced Tutorials/Python Scripting/Creating a GUI for your script

From Wikibooks, open books for an open world
Jump to: navigation, search

Often, your script will need to get information from the user, such as parameter settings, before performing its action. You can do this in two different ways: either present a modal popup that the user has to deal with before doing anything else, or alternatively you can take over the entire Scripts Window with a custom display that the user can freely switch to and from while doing other things.

A Modal GUI[edit]

The simplest way to add a GUI to your script is to pop up a simple menu with some items to choose from. Let’s add an option to our Tetrahedron Maker script to generate the tetrahedron upside-down. Displaying a menu is as simple as calling Blender.Draw.PupMenu and passing it a string containing the menu items separated by “|” characters. Put a “%t” at the end of the item that defines the menu title:

Orient = Blender.Draw.PupMenu("Add Tetrahedron%t|Right Way Up|Upside Down")

The value returned from the call will be the index of the selected menu item (starting from 1, ignoring the menu title), or -1 to indicate that no selection was made.

When you execute the above line, it displays this:

Blender249PopupMenuExample.png

We will use the menu selection to negate a scale factor which will be applied to the Z coordinate of the vertices of the tetrahedron. But only the last vertex has a nonzero Z coordinate, so this is the only one that needs a change in its computation. So the body of our script now looks like this:

Orient = Blender.Draw.PupMenu("Add Tetrahedron%t|Right Way Up|Upside Down")
if Orient > 0 :
    Scale = -1 if Orient > 1 else 1
    NewMesh = Blender.Mesh.New("Tetrahedron")
    NewMesh.verts.extend \
      (
        [
            (0, -1 / math.sqrt(3),0),
            (0.5, 1 / (2 * math.sqrt(3)), 0),
            (-0.5, 1 / (2 * math.sqrt(3)), 0),
            (0, 0, Scale * math.sqrt(2 / 3)),
        ]
      )
    NewMesh.faces.extend \
      (
        [[0, 1, 2], [0, 1, 3], [1, 2, 3], [2, 0, 3]]
      )
    TheObj = Blender.Object.New("Mesh", "Tetrahedron")
    TheObj.link(NewMesh)
    TheScene = Blender.Scene.GetCurrent()
    TheScene.link(TheObj)
    TheScene.update()
    Blender.Window.Redraw()
#end if

A Modeless GUI[edit]

It is very easy to create a GUI for your script, and that way make it easy to change aspects of it for everyone.

The command to create a Graphical User Interface (GUI) is:

Blender.Draw.Register(draw,event,button)

This command registers the functions:

  • draw - to draw the GUI
  • event - to action mouse and key presses
  • button - to action GUI button presses

However, this command will NOT work by itself !!!. You first need to define these 3 functions.


First we will import Blender's library of built in functions:

import Blender

Next, we will define the draw function.

def draw():

Inside this function we will draw the GUI. Here is an example of a drawing function we can use. It will clear the current window.

   Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)

And the next command will draw a button. Note that the first number in the command, '1' identifies the button as button 1. We will refer to this button later.

   Blender.Draw.Toggle("Clear origin",1,10,20,100,20,0,"Tooltip")

Next, we will define the event function. The code of a key pressed on the keyboard is passed into the function as the variable evt.

def event(evt,val):

Now we will test to see if the escape key is pressed:

   if evt == Blender.Draw.ESCKEY:

If it is pressed, exit the script, and return from the function:

           Blender.Draw.Exit()
                return 

Next, we will define the button function. This function will perform an action if the button is pressed.

def button(evt):

Now test the variable evt which holds the button number that we previously identified.

   if evt == 1:

If it is pressed, we will move the selected object in the 3d window back to the centre and redraw the screen:

           Blender.Scene.GetCurrent().getActiveObject().loc = (0,0,0)
                Blender.Window.Redraw()

Lastly, we can create the Graphical User Interface by typing the command:

Blender.Draw.Register(draw,event,button)


That's it !!! To enter the script yourself, type the following into the Text Editor window in Blender, and then press alt p to execute the script. Here's the entire script. Everything after the hash # is a comment and can be left out.

import Blender  # This will import the library of blender functions we will use
 
def draw():     # Define the draw function (which draws your GUI).
	Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT) # This clears the window
        # Add here drawing commands to draw your GUI, for example:
	Blender.Draw.Toggle("Clear origin",1,10,20,100,20,0,"Tooltip")
	# The line above will draw a toggle button.
	# Note the first number, '1' means this is button number 1
 
def event(evt,val):  # Define mouse and keyboard press events
	if evt == Blender.Draw.ESCKEY: # Example if esc key pressed
		Blender.Draw.Exit()    # then exit script
		return                 # return from the function
 
def button(evt):     # Define what to do if a button is pressed, for example:
	if evt == 1: # If button '1' is pressed, set active object to centre:
		Blender.Scene.GetCurrent().getActiveObject().loc = (0,0,0)
		Blender.Window.Redraw() # This will redraw the 3d window.
 
# You can now run the Graphical User Interface by typing the command:
 
Blender.Draw.Register(draw,event,button)
 
# End of script



Noob Note: When I tried to run that script it came up with an error: Attribute Error: 'Scene' object has no attribute 'getActiveObject'. I changed "Blender.Scene.GetCurrent().getActiveObject().loc = (0,0,0)" to "Blender.Scene.GetCurrent().objects.active.loc = (0,0,0)" and it worked.