An introduction to pyclutter (part one)

This tuto­r­ial is out­dated: it refers to ver­sion 0.4 of clut­ter that now is VERY old.

This tuto­r­ial is the first of a series that will try to learn to you how to use clut­ter with the help of python, or better: a tuto­r­ial about pyclutter.

But before to begin, it’s better to give an overview on what clut­ter is. Citing the clutter’s homepage:

Clut­ter is an open source soft­ware library for cre­at­ing fast, visu­ally rich and ani­mated graph­i­cal user inter­faces. Clut­ter uses OpenGL (and option­ally OpenGL ES) for ren­der­ing but with an API which hides the under­ly­ing GL com­plex­ity from the devel­oper. The Clut­ter API is intended to be easy to use, effi­cient and flex­i­ble.

That said, while clut­ter is the main library (writ­ten in C), there are bind­ings to other lan­guages like perl, vala, ruby, C# and python. The python bind­ing is com­monly named pyclutter.

The require­ments needed to better follow the tuto­r­ial are:

  • a good python knowledge (of course); if you don’t know it, you can always learn it by following the excellent dive into python
  • some basic knowledge of how the GTK environment works; although it isn’t really needed since we won’t use GTK functions, it is very useful since, under a certain point of view, clutter inherits many things from GTK
  • clutter 0.4.2 or newer

In clut­ter we have mainly two kind of objects: actors and con­tain­ers. Stages, addi­tion­ally, are a spe­cial kind of con­tainer. We can see the clut­ter actors like the GTK wid­gets and the stages like the GTK win­dows. A stage, as the doc­u­men­ta­tion says, is a top level “window” on which child actors are placed and manipulated.

Let see the stage as our work­space: in it we will place all the objects as we do with a GTK Window. So, let build our first clut­ter window:

import clutter

def main():
    stage = clutter.stage_get_default()
    stage.set_size(500, 500)
    stage.show()
    stage.connect("key-press-event", clutter.main_quit)

    clutter.main()

if __name__ == '__main__':
    main()

The above code will pro­duce this:

An example of stage

Well, that’s our first window :)
Now let ana­lyze every single line of the script:

import clutter

The line above is, prob­a­bly, the most impor­tant one in the script because with­out that line noth­ing will run. If you know Python you’ll already know what that line does, but if you’re a python newbie you need to under­stand that the import state­ment import the spec­i­fied name­space into the cur­rent script. That said, with that line, we can use clutter.

Let jump the main() for a while and let go to:

if __name__ == '__main__':
    main()

Apart from the main() call that is pretty obvi­ous, the line that could create some prob­lem is the one with the if state­ment. What it does is to call the main() only if __name__ is equal to __main__. So the ques­tion is: “when __name__ is ‘__main__’”? Every module has a built-​in attribute __name__, but it assumes the value __main__ only when you exe­cute that script: if the script is imported, instead, it will con­tain the module’s name.

Now jump into the main():

    stage = clutter.stage_get_default()

It’s better to spend some more time over the stage_get_default() method. We said that a stage is like a GTK window, but we didn’t cre­ated any window or stage because we don’t need to do so since clut­ter does it for us when we call clutter.main(). So we need a pointer to the newly cre­ated stage, and this pointer is a ClutterStage object that we can retrieve call­ing clutter.stage_get_default().

Now that we have a ref­er­ence to our stage and we have ini­tial­ized every­thing, we can begin to set prop­er­ties on our stage/window:

    stage.set_size(500, 500)

With the set_size method, we say that our stage should be 500x500px big. Pay atten­tion that we spec­ify the stage dimen­sions, that doesn’t includes the width and height of the dec­o­ra­tors that the window man­ager adds (like the title bar). Then we have:

    stage.show()

We call the show() method of the stage object because, by default, visual object like con­tain­ers and actors are hidden and we have explic­itly tell clut­ter to show them by using the actor’s show() method. If we don’t call this method we won’t see anything.

    stage.connect("key-press-event", clutter.main_quit)

Pay atten­tion to the above line. With that line we say to clut­ter to quit when some key on the key­board is pressed. That said, we con­nected an “event” to a “call­back func­tion” where, in this case, the event is key-press-event (that indi­cates that a key has been pressed) and the call­back is clutter.main_quit (with­out paren­the­sis because we are NOT call­ing it but, instead, we’re just giving it’s address so it can be called later by the clut­ter event han­dler). The clutter.main_quit() func­tion is the func­tion that clut­ter uses to stop the program’s exe­cu­tion and, with

    clutter.main()

starts and stop the pro­gram flow (clutter.main(), as the name says, is the func­tion that starts the program).

We did our first clut­ter pro­gram, and I think is enough for now. So let see you on the part two of this tuto­r­ial where I’ll begin to explain how to begin to insert some­thing into our stage.

Leave a comment ?

11 Comments.

  1. Ciao, ho letto questa tua intro­duzione a PyClut­ter ed ho provato ad eseguire il codice di esem­pio ma se lo incollo diret­ta­mente nella con­sole di python mi viene ese­guito cor­ret­ta­mente, se invece lo salvo in un file .py e lo eseguo da ter­mi­nale ottengo un mes­sag­gio di errore nel quale mi viene detto che il modulo clut­ter non ha un metodo stage_get_default(). Sai dirmi da cosa possa dipen­dere?

    p.s. Com­pli­menti per i tuto­r­ial

  2. Prob­a­bil­mente non hai impor­tato il modulo clut­ter, devi avere la riga import clutter prima di tutto, esat­ta­mente come nell’esempio.

  3. Il codice è iden­tico a quello ripor­tato nell’esempio, e uso lo stesso in entrambi i casi.

  4. Il metodo stage_get_default() deve esistere, altri­menti sig­nifica che c’è qualche prob­lema (nell’installazione di python/pyclutter o da qualche altra parte). Con­trolla di aver scritto tutto cor­ret­ta­mente, magari prova con un copy & paste, anche perché se fun­ziona inserendo il tutto nell’interprete, deve fun­zionare anche lan­ciando diret­ta­mente lo script.

  5. Stesso prob­lema:

    ste@Dirk:~/Desktop/progettiPython$ python Clutter_ex.py
    Trace­back (most recent call last):
    File “Clutter_ex.py”, line 12, in
    main()
    File “Clutter_ex.py”, line 4, in main
    stage = clut​ter.stage_get_default()
    Attrib­u­t­eEr­ror: ‘module’ object has no attribute ‘stage_get_default’

    python ha sempre fun­zion­ato e per clut­ter ho dato un sem­plice apt-​get install python-​clutter

  6. Io eseguo questi passi:
    - Copio il codice dal tuo arti­colo, lo incollo in un .py, lo lancio con “python file.py” e ottengo l’errore ripor­tato anche nel com­mento di Mater
    - Copio il codice dal tuo arti­colo, lo incollo nell’interprete python e tutto fun­ziona alla per­fezione

    Per l’installazione ho instal­lato sem­plice­mente il pac­chetto python-​clutter come Mater.

  7. Se usate ubuntu, forse abbi­amo trovato il prob­lema. Ho par­lato con uno degli svilup­pa­tori, sembra di capire che il pac­chetto ubuntu di pyclut­ter abbia grossi prob­lemi. Purtroppo non ho ancora potuto ver­i­fi­care di per­sona, ma spero di farlo nel pomerig­gio. La soluzione sarebbe usare la 0.4.2 “uffi­ciale”, ma può essere molto com­pli­cato com­pi­larla a mano per prob­lemi di dipen­denze e cose varie. Appena so qual­cosa di più, darò altre notizie.

  8. Si io uso ubuntu 7.10, allora attendo notizie e intanto provo a com­pi­larmi tutto a mano. Grazie dell’impegno

  9. Allora, ho disin­stal­lato il pac­chetto python-​clutter pre­sente nei repos­i­tory ubuntu e ho scar­i­cato dal sito del prog­etto la ver­sione 0.4.2 dei sor­genti. Poi ho com­pi­lato e instal­lato con con­fig­ure, make e make install ma con­tinuo ad avere lo stesso prob­lema. Ho sbagliato qual­cosa o forse la causa è diversa?

  10. Ciao, evi­tate di usare il metodo clutter.stage_get_default(), perche’ e’ dep­re­cato. Al posto suo bisogna usare clutter.Stage, quindi: stage = clutter.Stage().

  11. Hey, can you update this tuto­r­ial for newer ver­sions of pyclut­ter? (0.8 cur­rently). It would be really appre­ci­ated! :)

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">