An introduction to pyclutter (part one)
September 23rd, 2007
This tutorial is outdated: it refers to version 0.4 of clutter that now is VERY old.
This tutorial is the first of a series that will try to learn to you how to use clutter with the help of python, or better: a tutorial about pyclutter.
But before to begin, it’s better to give an overview on what clutter is. Citing the clutter’s homepage:
Clutter is an open source software library for creating fast, visually rich and animated graphical user interfaces. Clutter uses OpenGL (and optionally OpenGL ES) for rendering but with an API which hides the underlying GL complexity from the developer. The Clutter API is intended to be easy to use, efficient and flexible.
That said, while clutter is the main library (written in C), there are bindings to other languages like perl, vala, ruby, C# and python. The python binding is commonly named pyclutter.
The requirements needed to better follow the tutorial 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 clutter we have mainly two kind of objects: actors and containers. Stages, additionally, are a special kind of container. We can see the clutter actors like the GTK widgets and the stages like the GTK windows. A stage, as the documentation says, is a top level “window” on which child actors are placed and manipulated.
Let see the stage as our workspace: in it we will place all the objects as we do with a GTK Window. So, let build our first clutter 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 produce this:
Well, that’s our first window :)
Now let analyze every single line of the script:
import clutter
The line above is, probably, the most important one in the script because without that line nothing will run. If you know Python you’ll already know what that line does, but if you’re a python newbie you need to understand that the import statement import the specified namespace into the current 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 obvious, the line that could create some problem is the one with the if statement. What it does is to call the main() only if __name__ is equal to __main__. So the question is: “when __name__ is ‘__main__’”? Every module has a built-in attribute __name__, but it assumes the value __main__ only when you execute that script: if the script is imported, instead, it will contain 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 created any window or stage because we don’t need to do so since clutter does it for us when we call clutter.main(). So we need a pointer to the newly created stage, and this pointer is a ClutterStage object that we can retrieve calling clutter.stage_get_default().
Now that we have a reference to our stage and we have initialized everything, we can begin to set properties on our stage/window:
stage.set_size(500, 500)
With the set_size method, we say that our stage should be 500x500px big. Pay attention that we specify the stage dimensions, that doesn’t includes the width and height of the decorators that the window manager 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 containers and actors are hidden and we have explicitly tell clutter 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 attention to the above line. With that line we say to clutter to quit when some key on the keyboard is pressed. That said, we connected an “event” to a “callback function” where, in this case, the event is key-press-event (that indicates that a key has been pressed) and the callback is clutter.main_quit (without parenthesis because we are NOT calling it but, instead, we’re just giving it’s address so it can be called later by the clutter event handler). The clutter.main_quit() function is the function that clutter uses to stop the program’s execution and, with
clutter.main()
starts and stop the program flow (clutter.main(), as the name says, is the function that starts the program).
We did our first clutter program, and I think is enough for now. So let see you on the part two of this tutorial where I’ll begin to explain how to begin to insert something into our stage.
Ciao, ho letto questa tua introduzione a PyClutter ed ho provato ad eseguire il codice di esempio ma se lo incollo direttamente nella console di python mi viene eseguito correttamente, se invece lo salvo in un file .py e lo eseguo da terminale ottengo un messaggio di errore nel quale mi viene detto che il modulo clutter non ha un metodo stage_get_default(). Sai dirmi da cosa possa dipendere?
p.s. Complimenti per i tutorial
Comment by Francesco — November 5th, 2007 at 14:52
Probabilmente non hai importato il modulo clutter, devi avere la riga
import clutterprima di tutto, esattamente come nell’esempio.Comment by Giuliani Vito, Ivan — November 6th, 2007 at 20:00
Il codice è identico a quello riportato nell’esempio, e uso lo stesso in entrambi i casi.
Comment by Francesco — November 7th, 2007 at 19:28
Il metodo
stage_get_default()deve esistere, altrimenti significa che c’è qualche problema (nell’installazione di python/pyclutter o da qualche altra parte). Controlla di aver scritto tutto correttamente, magari prova con un copy & paste, anche perché se funziona inserendo il tutto nell’interprete, deve funzionare anche lanciando direttamente lo script.Comment by Giuliani Vito, Ivan — November 7th, 2007 at 22:51
Stesso problema:
ste@Dirk:~/Desktop/progettiPython$ python Clutter_ex.py
Traceback (most recent call last):
File “Clutter_ex.py”, line 12, in
main()
File “Clutter_ex.py”, line 4, in main
stage = clutter.stage_get_default()
AttributeError: ‘module’ object has no attribute ‘stage_get_default’
python ha sempre funzionato e per clutter ho dato un semplice apt-get install python-clutter
Comment by Mater — November 8th, 2007 at 15:50
Io eseguo questi passi:
- Copio il codice dal tuo articolo, lo incollo in un .py, lo lancio con “python file.py” e ottengo l’errore riportato anche nel commento di Mater
- Copio il codice dal tuo articolo, lo incollo nell’interprete python e tutto funziona alla perfezione
Per l’installazione ho installato semplicemente il pacchetto python-clutter come Mater.
Comment by Francesco — November 8th, 2007 at 20:17
Se usate ubuntu, forse abbiamo trovato il problema. Ho parlato con uno degli sviluppatori, sembra di capire che il pacchetto ubuntu di pyclutter abbia grossi problemi. Purtroppo non ho ancora potuto verificare di persona, ma spero di farlo nel pomeriggio. La soluzione sarebbe usare la 0.4.2 “ufficiale”, ma può essere molto complicato compilarla a mano per problemi di dipendenze e cose varie. Appena so qualcosa di più, darò altre notizie.
Comment by Giuliani Vito, Ivan — November 10th, 2007 at 10:39
Si io uso ubuntu 7.10, allora attendo notizie e intanto provo a compilarmi tutto a mano. Grazie dell’impegno
Comment by Francesco — November 10th, 2007 at 14:28
Allora, ho disinstallato il pacchetto python-clutter presente nei repository ubuntu e ho scaricato dal sito del progetto la versione 0.4.2 dei sorgenti. Poi ho compilato e installato con configure, make e make install ma continuo ad avere lo stesso problema. Ho sbagliato qualcosa o forse la causa è diversa?
Comment by Francesco — November 10th, 2007 at 15:35
Ciao, evitate di usare il metodo
clutter.stage_get_default(), perche’ e’ deprecato. Al posto suo bisogna usareclutter.Stage, quindi:stage = clutter.Stage().Comment by Ali Servet Dönmez — July 21st, 2008 at 14:46
Hey, can you update this tutorial for newer versions of pyclutter? (0.8 currently). It would be really appreciated! :)
Comment by Armin — August 3rd, 2009 at 23:29