[LinuxFocus-icon]
Home  |  Plan  |  Index  |  Suchen

Nachrichten | Archiv | Links | Über uns
Dieser Artikel ist verfübar in: English  Castellano  Deutsch  Francais  Turkce  

convert to palmConvert to GutenPalm
or to PalmDoc

Hilaire Fernandes
von Hilaire Fernandes
<hfernandes(at)april.org>

Über den Autor:

Hilaire Fernandes ist der Vize-Präsident von OFSET, einer Organisation, welche es sich zur Aufgabe gemacht hat, die Entwicklung freier Lernsoftware für das Gnome Desktop Projekt zu unterstützen. Er schrieb Dr. Geo, ein preisgekröntes Geometrieprogramm. Momentan arbeitet er an Dr. Genius, einem weiteren mathematischem Lernprogramm für Gnome.



Übersetzt ins Deutsche von:
Harald Radke <harryrat(at)postnuklear.de>

Inhalt:

 

Gnome Programmentwicklung mit Python (Part 1)

Gnome

Zusammenfassung:

Diese Artikelserie zielt speziell auf die Neulinge unter den Lesern in Sachen Gnome Programmierung und GNU/Linux ab. Die gewählte Programmiersprache, Python, kommt ohne den sonst bei compilerorientierten Sprachen, wie etwa C, üblichen Ballast aus. Gewisse Grundkenntnisse über Python sind für das Verständnis dieses Artikels notwendig.



 

Notwendige Werkzeuge

Die in diesem Artikel vorgestellten Programme benötigen folgende Werkzeuge:

Python-Gnome und LibGlade Installation vom Quelltext aus:

./configure
make
make install

sollte es tun. (Ausführlichere Informationen kann man unter
http://www.linuxgazette.com/issue38/pollman.html] finden Die Umgebungsvariable PYTHONPATH muss auf den Verzeichnispfad zeigen, unter welchem die Python-Gnome Bindungen installiert worden sind. Diese sind häufig zu finden unter: /usr/local/lib/python1.5/site-packages oder /usr/lib/python1.5/site-packages/. Dort befinden alle für Gnome und LibGlade notwendigen Dateien, zum Beispiel liegt dort libglade.py. Die Variable PYTHONPATH wird einfach dadurch gesetzt, dass man folgende Zeilen in seine .bash_profile Datei eintträgt:

PYTHONPATH=/usr/local/lib/python1.5/site-packages
export PYTHONPATH

Nicht vergessen, es kann sein, dass man seinen Python Code von einem Terminal aus ausführen muss, damit die Variable gesetzt ist.


 

Interaktion von Glade, LibGlade & Python

Glade ist ein von Damon Chaplin entwickeltes Programm zur interaktiven Generierung von Programmen mit einer grafischer Oberfläche, in diesem Fall unter der Verwendung von Gnome/Gtk. In Glade kann die erzeugte Oberfläche in einer XML Datei gespeichert oder direkt in C Code überführt werden, um dann in einer C Quelltextdatei verwendet zu werden. Glade erlaubt desweiteren die Benennung der Handler/Funktionen, welche den jeweiligen Ereignissen der Oberfläche (Events) zugeordnet werden sollen. Beispielsweise kann die Funktion (genauer: deren Name) bestimmt werden, die bei der Auswahl eines bestimmten Menüpunktes aufgerufen werden soll.

LibGlade ist eine Bibliothek, welche Funktionen bietet, um eine grafische Oberfläche aus einer XML Datei heraus direkt zu erzeugen. Entwickelt wurde LibGlade von James Henstridge. Die jeweilige Applikation muss nur die XML Datei erkennen, im Allgemeinen besitzt sie die Endung .glade. LibGlade konstruiert dann aus ihr die Oberfläche. James Henstridge hat auch die LibGlade Python Bindungen geschrieben, welche neben anderen, im Gnome-Python Paket zu finden sind. LibGlade gestattet auch das (beinahe )automatische Verbinden der Funktionen, die in der .glade Datei deklariert worden, sind mit Funktionen im Python Code.

Folgendes Diagramm zeigt den Mechanismus allgemein. Um die Implmentierung der Python Bindungen zu verstehen, kann es manchmal notwendig sein, einen Blick auf die Gtk, Gnome und LibGlade Module von Python zu werfen, die in PYTHONPATH liegen, um sie mit der C Gtk/Gnome Entwickler Dokumentation zu vergleichen.

 

Erstes Beispiel: Color

Für den Einstieg in die Gnome-Python Programmierung dient ein einfaches Farben Spiel, bei welchem Kinder Figuren der gleichen Farbe erkennen sollen. Dieses sehr graphisch orientierte Beispiel verwendet einige sehr schöne Gnome Widgets, wie etwa die Gnome Canvas und das Gnome Applikationsfenster. Die Spielregeln sind recht einfach: Das Spielfeld beinhaltet 16 Figuren, Kreise, Sterne und Quadrate, in verschiedenen Farben, die 8 Farbenpaare bilden. Sinn des Spieles ist es nun, nacheinander alle 8 Paare auszuwählen. Wer mag, kann erstmal einen Blick auf den Quelltext am Ende dieses Artikels werfen, um eine generelle Vorstellung zu bekommen und dann von hier aus weiterelesen.

 

Mit Glade eine graphische Oberfläche erstellen

Die Widgets

Nach dem Start von Glade erscheinen zwei Fenster. Eines ist eine Widget Werkzeugleiste namens Palette. Hier können aus den Kategorien GTK+ Basic, GTK+ Additional und Gnome die jeweiligen Objekte ausgesucht werden. Sind keine Gnome Widgets zu finden, wurde Glade möglicherweise ohne Gnome Unterstützung übersetzt. In diesem Fall sollte die Datei confiugre des Quelltext Paketes von Glade überprüft werden, mit configure --help werden die Optionen ausgegeben.

In dem anderen Fenster werden im Hauptteil die erzeugten Widgets aufgeführt.

Zuerst wird ein Gnome Applikationsfenster erzeugt. Dies ist ein Widget mit einem Menü und einer Werkzeugleiste. Beide sind frei beweglich. Am unteren Ende des Applikationsfensters befindet sich eine Statusleiste. Nachdem das Gnome Applikationsfenster erzeugt worden ist, kann man durch Öffnen des Widget Tree Dialoges (zu finden im Menü View von Glade) genauer herausfinden, welche Elemente genau dieses Widget enthält.

Nun wird eine Canvas im Hauptteil des Applikationsfenster erzeugt. Im Properties Dialog werden die maximale Größe und die Koordinaten der Canvas jeweils auf 400 gesetzt.


Als nächstes wird ein Gnome About Dialog generiert. Dessen Inhalt kann im Properties Dialog des Widgets geändert werden.

Diese Widgets sind alle in der Klasse Gnome der Werkzeugleiste Palette zu finden.

Nun sollten die nicht verwendetetn Iconknöpfe und Menüeinträge entfernt werden. In der Werkzeugleiste werden die Knöpfe Open und Save entfernt. Danach wird die Menüleiste editiert (mit der rechten Maustaste auf sie klicken und Edit Menu auswählen). Bis auf File->New, File->Exit, Setting->Preferences und Help->About werden alle Punkte entfernt.

Widget- und Handlernamen festlegen

Es werden die folgenden Namen den jeweiligen Elementen zugeordnet, sodass sie unter diesen in Python angesprochen werden können:

Gnome Applikationsfenster:
colorApp
Gnome About Dialog:
about

Die Namen der Handler sind die Namen der Funktionen, die bei Auftreten eines bestimmten Schnittstellenereignisses (Event) eines Widgets aufgerufen werden sollen. Dies bedeutet, dass später in Python Funktionen definiert werden, die, jedenfalls beinahe, diese Namen erhalten, wie später zu sehen sein wird. Beispielsweise soll beim Betätigen des Iconknopfes New eine Funktion aufgerufen werden, die das Spiel neu starten soll. Dazu muss in Glade ein Widget ausgewählt und dieses mittels des Signals Fensters (im Properties Dialog zu finden) entsprechend angepasst werden.

Im obigen Beispiel ist das richtige Signal clicked und der Handler der Funktionsname. Die folgende Tabelle führt alle Signale und Handler auf:

Im About Dialog:

Widget Name Signal Handler
about clicked gtk_widget_destroy
about close gtk_widget_destroy
about destroy gtk_widget_destroy

Der Handler gtk_widget_destroy ist eine vordefinierte GTK Funktion, welche einfach das Widget schließt.

Für das Fenster colorApp werden von Glade automatisch die Signale und Handler der Menüpunkte eingetragen. Die jeweiligen Namen sind in unten stehender Tabelle zu finden. Wie man sieht, verwenden sowohl der Menüunterpunkt New, als auch der entsprechende Knopf den selben Handler, haben sie doch den gleichen Zweck:

Widget Name Signal Handler
button1 (new icon button
on the toolbar
clicked on_new_activate
new activate on_new_activate
colorApp destroy on_exit1_activate
exit1 activate on_exit1_activate
about1 activate on_about_activate

Der letzte Schliff

Es wird der Punkt Project Options über den Knopf Options der Glade Werkzeugleiste ausgewählt. In der Karte General, werden nun für das Projekt die unten gezeigten Einstellungen vorgenommen:

Die Datei, die die Widgets beschreibt, heisst color.glade. Der Pfad zum jeweiligen Heimatverzeichnis muss angepasst werden.

Nun kann die Datei vom File Menü aus gespeichert werden. Von der Möglichkeit, selbst Quelltext zu erzeugen, wird hier nicht Gebrauch gmeacht.
Soviel zu Glade, nun geht es mit Python weiter

 

Der Python Code

Der vollständige Quelltext ist am Ende des Artikels zu finden. Er muss im gleichen Verzeichnis, wie die Datei color.glade abgespeichert werden.

 

Einbinden aller notwendigen Module

from math import cos, sin, pi
from whrandom import randint
from gtk import *
from gnome.ui import *
from GDK import *
from libglade import *

Aus den Modulen math und whrandom werden einige, nicht Gnome spezifische, Funktionen wie etwa cos, sin, randint und die Konstante pi eingebunden. Die Gnome spezifischen Module sind gtk, GDK und gnome.ui. In C reicht es aus, gnome.h für alle Gnome Headerdateien einzubinden. In Python ist es notwendig, zuerst herauszufinden, in welchem Modul die Bindung für die jeweilige Gnome Funktion, die man haben will, zu finden ist. In einem Terminalfenster (Shell) kann man zum Beispiel mit folgendem Kommando nach dem Modul suchen, welches die Zeichenkette "canvas" beinhaltet:

cd /usr/local/lib/python1.5/site-packages/gnome
grep canvas *.py

Hierbei wurde angenommen, dass die Gnome Bindungen unter /usr/local/lib/python1.5/site-packages zu finden sind.

 

Laden der graphischen Oberfläche mit Libglade

In diesem Beispiel für Python wird die Gnome Canvas für die Manipulation von Figuren, also der Sterne, Kreisen und Dreiecken, verwendet. Eine Canvas ist ein "Leinwand" für die Darsteullung beliebiger graphischer Elemente (etwa Ellipsen, Punkten, Linien oder Rechtecken), Textelemente oder gar anderer Widgets. Eine Canvas kann auch weitere Canvasgruppen enthalten. In solcher einer Gruppen werden dann die Elemente der Canavas plaziert, in diesem Fall die unterschiedlichen Figuren. Es gibt eine Standardgruppe, die sogenannte Wurzelgruppe (root canvas group). In dieser werden die Figuren plaziert.

Zuerst werden einige globale Variablen definiert:

Die erste Funktion, die aufgerufen wird, ist initColor. Sie erzeugt die Widgets aus der Datei color.glade heraus und verbindet die Handler mit den Widgets.

def initColor ():
    global rootGroup, canvas
    wTree = GladeXML ("color.glade",
                      "colorApp")
    dic = {"on_about_activate": on_about_activate,
           "on_exit1_activate": mainquit,
           "on_new_activate":on_new_activate}
    wTree.signal_autoconnect (dic)
    canvas = wTree.get_widget ("canvas")
    rootGroup = canvas.root ()

Die Widgets werden mittels der Funktion GladeXML erzeugt. Dafür muss natürlich der Pfad der Datei color.glade entsprechend angegeben werden. Die Funktion generiert das Gnome Applikationsfenster colorApp, welches mit Glade definiert wurde und stellt es dar. Sie liefert ein Objekt, einer richtigen Klasse, zurück, dass einige nützliche Methoden bereitstellt.

Als nächstes werden Handler, die in Python definiert worden sind (dazu später mehr) mit den in der Datei color.glade definierten Widgets verbunden. Dazu muss eine Tabelle erzeugt werden, in der entsprechende Schlüsseleinträge für jeden Handlername, der in der Datei color.glade definiert worden ist, erstellt werden: on_about_activate, on_exit1_activate und on_new_activate. Jedem dieser Einträge wird der Name einer in Python definierten Funktion zugwiesen.
Schließlich erledigt die Methode signal_autoconnect den Rest.

Zuletzt werden noch die Verweise auf die Canvas, die während des GladeXML Aufrufes erzeugt worden ist (ein GnomeCanvas Objekt in Python) und auf die Wurzelgruppe, ein GnomeCanvasGroup Objekt, gesichert.

Nützliche Tips

Es existiert keine wirkliche Dokumentation, welche die Gnome Bindungen für Python beschreiben. Jedoch kann man recht viel Material über die Gnome Programmierung in C finden, und zwar auf der Gnome WWW Site. Diese Dokumentation kann recht hilfreich sein, allerdings wird man schon ein wenig in die Gnome Bindung für Python selbst reinschauen müssen, um sie wirklich nutzen zu können:

Zu finden ist sie unter /usr/local/lib/python1.5/site-packages/gnome/ oder /usr/lib/python1.5/site-packages/gnome/

Was man erfährt:

  1. in libglade.py:
    • GladeXML is in Wirklichkeit ein Objekt, es wurde also eigentlich der __init__ Konstruktor aufgerufen. Das erste Argument, welches übergeben wird, ist filename, wie erwartet. self ist ein automatisch generiertes Argument, welches eine Referenz auf das aktuelle Objekt ist. Das zweite Argument root ist der Name des Toplevel Widgets, in welchem die ganze graphische Oberfläche realisiert werden soll. Diese Methode ruft dann eine C Funktion namens glade_xml_new_with_domain auf. In der C Dokumentation zu LibGlade kann man mehr über glade_xml_new_with_domain erfahren.
    • Das Objekt GladeXML besitzt eine Methode mit dem Namen get_widget. Diese macht nichts weiter, als die C Funktion glade_get_widget aufzurufen.
      Wenn also canvas = wTree.get_widget("canvas") ausgeführt wird, wird glade_xml_get_widget aufgerufen.
  2. in gnome/ui.py:
    • Die Klasse GnomeCanvas besitzt die Methode root, welche im Python Code verwendet wird. Diese Methode ruft die C Funktion gnome_canvas_root auf.

Für jeden Einsatz von Gnome in Python kann man so an die entsprechende Dokumentation kommen. Der Leser sollte sich mit der jeweiligen Gnome Dokumentation auseinandersetzen und so mehr über diese Funktionen lernen.

 

Definition der Handler

Drei Handler werden mit der Oberfläche verbunden. Diese sind: on_about_activate, on_new_activate und mainquit. Letzterer ist eine Python Funktion, durch welche das Programm (und Python) verlassen wird.

def on_about_activate(obj):
    "display the about dialog"
    about = GladeXML ("color.glade", "about").get_widget ("about")
    about.show ()

Dieser Handler öffnet das About Fenster. Zuerst wird eine Referenz auf den about Dialog gesichert. GladeXML erzeugte ihn bereits durch das GladeXML Objekt. Wie oben schon erwähnt, ist GladeXML ein Python Objekt, u.a. mit der Methode get_widget. Diese liefert ein Objekt vom Typ GtkWidget zurück, welches eine Methode show besitzt.

Tips

Ein Blick auf GtkWidget in der Datei gtk.py zeigt, dass dieses die Methode show besitzt. Obiger Handler kann also auch so implementiert werden: GladeXML("color.glade","about").get_widget("about").show().

def on_new_activate (obj):
    global rootGroup, colorShape
    for item in colorShape:
        item.destroy ()
    del colorShape[0:]
    buildGameArea (rootGroup)

Diese Funktion erzeugt eine neue Spielfläche. Die noch existierenden Figuren werden zuerst zerstört. Die Formen sind Objekte vom Typ GnomeCanvasItem, abgeleitet von der Klasse GtkObject. In dieser Klasse ist auch die Methode destroy zu finden. Danach wird die neue Spielfläche erzeugt.

 

GnomeCanvasItem

Definition der Figuren

Die Funktion buildGameArea steuert die Generierung des Spielfeldes und der GnomeCanvasGroup Gruppe. Die Figuren, vom Typ GnomeCanvasItem, werden über Aufrufe von buildShape erzeugt. Als Figuren kommen Kreise, Quadrate oder Sterne in Frage.

Die Figuren werden in Abhängigkeit der jeweiligen Form erzeugt:

item = group.add ("ellipse", x1 = x - r, y1 = y - r,
                  x2 = x + r, y2 = y + r, fill_color = color,
                  outline_color = "black", width_units = 2.5)

[...]

item = group.add ("rect", x1 = x - a, y1 = y - a,
                  x2 = x + a, y2 = y + a, fill_color = color,
                  outline_color = "black", width_units = 2.5)

[...]

item = group.add ("polygon", points = pts, fill_color = color,
                  outline_color = "black", width_units = 2.5)

Die Variable group verweist auf ein Objekt vom Typ GnomeCanvasGroup. Ein Blick in die Datei ui.py zeigt auf, dass die Klasse GnomeCanvasGroup ein Methode namens add besitzt. Deren erstes Argument tp erwartet eine Zeichenkette, die den Typ des Elementes, welches hinzugefügt werden soll, angibt. Als weitere Argumente sind Paare von Schlüsselwörtern und Werten. Für einen Überblick der gültigen Schlüsselwörter sollte man sich die Klassen GnomeCanvasRect, GnomeCanvasEllipse und GnomeCanvasPolygon in ui.py anschauen.

ellipse und rectangle sind ziemlich ähnlich, die beiden Abszissen- und Ordinatenwerte beschreiben die obere linke, sowie die untere rechte Ecke ihres umschließenden Rechteckes (top-left und bottom-right). Der Koordinatenursprung der Canvas ist standardmäßig oben links (top-left). polygon erwartet points als Werte, ein Liste von Koordinatenpaaren, die die Punkte des Polygones bestimmen. Die weiteren Argumente sind selbsterklärend.

Ereignisbehandlung der Formen

Jeder Figur, die erzeugt wird, wird ein Ereignis (Event) zugeordnet. Dies wird am Ende der Funktion buildShape getan.

item.connect ('event', shapeEvent)
colorShape.append (item)

Dafür wird einfach die Methode connect der Klasse GtkObject, eine Oberklasse von GnomeCanvasItem, verwendet. Als erstes Argument wird das Signal übergeben. Da GnomeCanvasEvent mit einem einzigen Signal, namentlich event, alle Ereignisse abdeckt, wird einfach event übergeben. Der zweite Parameter ist der Name des Handlers, hier shapeEvent. Optional kann noch ein drittes Argument übergeben werden, was aber hier nicht notwendig ist. Das wars !

 

Events der Figuren

Hier nun der Event-Handler für die Figuren:

def shapeEvent (item, event):
    global selectedItem, itemToSelect, colorShape
    if event.type == ENTER_NOTIFY and selectedItem != item:
        #highligh outline
        item.set(outline_color = 'white')
    elif event.type == LEAVE_NOTIFY and selectedItem != item:
        #unlight outline
        item.set(outline_color = 'black')
    elif event.type == BUTTON_PRESS:
        #select the item
        if not selectedItem:
            item.set (outline_color = 'white')
            selectedItem = item
        elif item['fill_color_gdk'] == selectedItem['fill_color_gdk'] \
             and item != selectedItem:
            #destroy both item
            item.destroy ()
            selectedItem.destroy ()
            colorShape.remove (item)
            colorShape.remove (selectedItem)
            selectedItem, itemToSelect = None, itemToSelect - 1
            if itemToSelect == 0:
                buildGameArea (rootGroup)
    return 1

Wird dieser Handler aufgerufen, so verweist item auf die jeweilige Figur, die von dem Ereignis betroffen ist. Desweiteren steht in event die Art des Ereignisses. An GdkEvent Ereignissen interessant sind hier nur die folgenden drei:

Der Handler liefert immer TRUE(1) zurück. Dadurch wird das Event Signal nicht zu weiteren Elementen durchgereicht. Dies ist nicht auch notwendig, da die Figuren sich nicht überdecken.

 

Zum Schluss

Jeglicher Python Code, der nicht für Gnome relevant war, wurde ausgelassen, ihn zu verstehen sollte nicht so schwer sein. Ziel dieses Artikels war es, dem Leser zu zeigen, wie er selbständig herausfinden kann, was wo wie funktioniert: Dazu wurde in die Gnome Bindungen von Python, die Gnome C Headerdateien und in die Dokumentation zur Programmierung von Gnome in C geschaut. Natürlich wurde desweiteren gezeigt, wie einfach und doch mächtig Gnome Canvas und Glade/LibGlade sind. Der Leser kann von hier aus weiter experimentieren und den Quelltext erweitern (die Quelltextdateien sind hier zu finden).

 

Anhang: Der ganze Quelltext

#!/usr/bin/python
# Couleur - Teo Serie
# Copyright Hilaire Fernandes 2000
# Release under the terms of the GPL licence version 2
# You can get a copy of the license at http://www.gnu.org
#
# Select shapes with same color
#
from math import cos, sin, pi
from whrandom import randint
from gtk import *
from gnome.ui import *
from GDK import *
from libglade import *

width, itemToSelect = 400, 8
selectedItem = rootGroup = canvas = None
# to keep trace of the canvas item
colorShape =[];

def on_about_activate(obj):
    "display the about dialog"
    about = GladeXML ("color.glade", "about").get_widget ("about")
    about.show ()

def on_new_activate (obj):
    global rootGroup, colorShape
    for item in colorShape:
        item.destroy ()
    del colorShape[0:]
    buildGameArea (rootGroup)

def shapeEvent (item, event):
    global selectedItem, itemToSelect, colorShape
    if event.type == ENTER_NOTIFY and selectedItem != item:
        #highligh outline
        item.set(outline_color = 'white')
    elif event.type == LEAVE_NOTIFY and selectedItem != item:
        #unlight outline
        item.set(outline_color = 'black')
    elif event.type == BUTTON_PRESS:
        #select the item
        if not selectedItem:
            item.set (outline_color = 'white')
            selectedItem = item
        elif item['fill_color_gdk'] == selectedItem['fill_color_gdk'] \
             and item != selectedItem:
            #destroy both item
            item.destroy ()
            selectedItem.destroy ()
            colorShape.remove (item)
            colorShape.remove (selectedItem)
            selectedItem, itemToSelect = None, itemToSelect - 1
            if itemToSelect == 0:
                buildGameArea (rootGroup)
    return 1

def buildShape (group, number, type, color):
    "build a shape of 'type' and 'color'"
    global colorShape
    w = width / 4
    x, y, r = (number % 4) * w + w / 2, (number / 4) * w + w / 2, w / 2 - 2
    if type == 'circle':
        item = buildCircle (group, x, y, r, color)
    elif type == 'squarre':
        item = buildSquare (group, x, y, r, color)
    elif type == 'star':
        item = buildStar (group, x, y, r, 0.4, randint (3, 15), color)
    elif type == 'star2':
        item = buildStar (group, x, y, r, 0.6, randint (3, 15), color)
    item.connect ('event', shapeEvent)
    colorShape.append (item)

def buildCircle (group, x, y, r, color):
    item = group.add ("ellipse", x1 = x - r, y1 = y - r,
                      x2 = x + r, y2 = y + r, fill_color = color,
                      outline_color = "black", width_units = 2.5)
    return item

def buildSquare (group, x, y, a, color):
    item = group.add ("rect", x1 = x - a, y1 = y - a,
                      x2 = x + a, y2 = y + a, fill_color = color,
                      outline_color = "black", width_units = 2.5)
    return item

def buildStar (group, x, y, r, k, n, color):
    "k: factor to get the internal radius"
    "n: number of branch"
    angleCenter = 2 * pi / n
    pts = []
    for i in range (n):
        #external points of the star
        pts.append (x + r * cos (i * angleCenter))
        pts.append (y + r * sin (i * angleCenter))
        #internal points of the star
        pts.append (x + r * k * cos (i * angleCenter + angleCenter / 2))
        pts.append (y + r * k * sin (i * angleCenter + angleCenter / 2))
    pts.append (pts[0])
    pts.append (pts[1])
    item = group.add ("polygon", points = pts, fill_color = color,
                      outline_color = "black", width_units = 2.5)
    return item

def getEmptyCell (l, n):
    "get the n-th non null element of l"
    length, i = len (l), 0
    while i < length:
        if l[i] == 0:
            n = n - 1
        if n < 0:
            return i
        i = i + 1
    return i

def buildGameArea (group):
    global itemToSelect, selectedItem
    itemColor = ['red', 'yellow', 'green', 'brown', 'blue', 'magenta',
                 'darkgreen', 'bisque1']
    itemShape = ['circle', 'squarre', 'star', 'star2']
    emptyCell = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    itemToSelect, i, selectedItem = 8, 15, None
    for color in itemColor:
        # two items of same color
        n = 2
        while n > 0:
            cellRandom = randint (0, i)
            cellNumber = getEmptyCell (emptyCell, cellRandom)
            emptyCell[cellNumber] = 1
            buildShape (group, cellNumber, itemShape[randint (0, 3)], color)
            i, n = i - 1, n - 1

def initColor ():
    global rootGroup, canvas
    wTree = GladeXML ("color.glade",
                      "colorApp")
    dic = {"on_about_activate": on_about_activate,
           "on_exit1_activate": mainquit,
           "on_new_activate":on_new_activate}
    wTree.signal_autoconnect (dic)
    canvas = wTree.get_widget ("canvas")
    rootGroup = canvas.root ()

initColor ()
buildGameArea (rootGroup)
mainloop ()
 

Talkback für diesen Artikel

Jeder Artikel hat seine eigene Seite für Kommentare und Rückmeldungen. Auf dieser Seite kann jeder eigene Kommentare abgeben und die Kommentare anderer Leser sehen:
 Talkback Seite 

Der LinuxFocus Redaktion schreiben
© Hilaire Fernandes, FDL
LinuxFocus.org

Einen Fehler melden oder einen Kommentar an LinuxFocus schicken
Autoren und Übersetzer:
en --> -- : Hilaire Fernandes <hfernandes(at)april.org>
en --> de: Harald Radke <harryrat(at)postnuklear.de>

2002-02-24, generated by lfparser version 2.25

mirror server hosted at Truenetwork, Russian Federation.