Stage Widget

The cluttergtk.Embed widget allows you to place a clutter.Stage inside an existing PyGTK window. For instance, the window might contain other PyGTK widgets allowing the user to affect the actors in stage. Use cluttergtk.Embed() to instantiate the widget and then add it to a container just like any other PyGTK widget. Call embed.get_stage() to get the clutter.Stage from the cluttergtk.Embed widget so you can then use the main PyClutter API.

When using the cluttergtk.Embed widget you should import the cluttergtk module before the clutter module. You should use the regular gtk.main() function to start the mainloop rather than clutter.main().

For simplicity, all other examples in this document will instead use clutter.Stage(), but all the techniques can also be used with a stage inside the cluttergtk.Embed widget.

Reference

GTK+ integration

PyClutter contains some useful utility functions to help you integrate your use of GTK+ and the parts you draw with PyClutter.

To embed stock or other icons into clutter you can use the cluttergtk.Texture and the texture.from_{stock,file}() functions. If you need to draw in the correct theme colors then the cluttergtk.get_*_color() functions can receive a theme color for a gtk.Widget in the current state and convert it to a clutter.Color for use with PyClutter.

Example

The following example shows a cluttergtk.Embed PyGTK widget and changes the stage color when a button is clicked.

Note that this example requires the clutter-gtk-1.0 and the clutter-1.0 packages.

Figure 3.2. Stage Widget

Stage Widget

Source Code

File: main.py

import sys

import cluttergtk   # must be the first to be imported
import clutter
import gtk


already_changed = False
stage = None


def on_button_clicked(button):
    global already_changed, stage

    if already_changed:
        stage_color = clutter.Color(0, 0, 0, 255) # Black
        stage.set_color(stage_color)
    else:
        stage_color = clutter.Color(32, 32, 160, 255)
        stage.set_color(stage_color)

    already_changed = not already_changed

    return True # Stop further handling of this event


def on_stage_button_press(stage, event):
    print "Stage clicked at (%f, %f)" % (event.x, event.y)

    return True # Stop further handling of this event


def main ():
    global stage

    stage_color = clutter.Color(0, 0, 0, 255) # Black

    # Create the window and add some child widgets
    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    vbox = gtk.VBox(False, 6)
    window.add(vbox)
    vbox.show()
    button = gtk.Button("Change Color")
    vbox.pack_end(button, False, False, 0)
    button.show()
    button.connect('clicked', on_button_clicked)

    # Stop the application when the window is closed
    window.connect('hide', gtk.main_quit)

    # Create the clutter widget
    clutter_widget = cluttergtk.Embed()
    vbox.pack_start(clutter_widget, True, True, 0)
    clutter_widget.show()

    # Set the size of the widget,
    # because we should not set the size of its stage when using GtkClutterEmbed.
    clutter_widget.set_size_request(200, 200)

    # Get the stage and set its size and color
    stage = clutter_widget.get_stage()
    stage.set_color(stage_color)

    # Show the stage
    stage.show()

    # Connect a signal handler to handle mouse clicks and key presses on the stage
    stage.connect("button-press-event", on_stage_button_press)

    # Show the window
    window.show()

    # Start the main loop, so we can respond to events:
    gtk.main()

    return 0


if __name__ == '__main__':
    sys.exit(main())