Der Code
Das Programm selbst findet sich in Listing 2. Es enthält knapp über 60 Zeilen Python und ist recht simpel gestrickt. Die gesamte Anwendung besteht aus der Definition der Klasse »TemperaturApp«
(Zeile 11), die neben dem Konstruktor »__init__()«
die Methoden »main()«
, »delete_event()«
, »destroy()«
und »geaendert()«
umfasst.
Listing 2
temperatur.py
01 #!/usr/bin/python
02 import pygtk
03 pygtk.require('2.0')
04 import gtk
05
06 felder = "kelvin-feld", "celsius-feld", "fahrenheit-feld", "reaumur-feld", "rankine-feld"
07 wert = {}
08 widget = {}
09 handler = {}
10
11 class TemperaturApp:
12
13 def delete_event(self, widget, event, data=None):
14 return False
15
16 def destroy(self, widget, data=None):
17 gtk.main_quit()
18
19 def geaendert(self, objekt, was):
20 wert[was] = widget[was].get_value()
21 if was == "celsius-feld":
22 wert["kelvin-feld"] = wert["celsius-feld"] + 273.15
23 elif was == "fahrenheit-feld":
24 wert["kelvin-feld"] = (5.0/9.0)*(wert["fahrenheit-feld"]-32.0) + 273.15
25 elif was == "reaumur-feld":
26 wert["kelvin-feld"] = (5.0/4.0)*wert["reaumur-feld"] + 273.15
27 elif was == "rankine-feld":
28 wert["kelvin-feld"] = (5.0/9.0)*wert["rankine-feld"]
29
30 if was != "celsius-feld":
31 wert["celsius-feld"] = wert["kelvin-feld"] - 273.15
32 if was != "fahrenheit-feld":
33 wert["fahrenheit-feld"] = (9.0/5.0)*(wert["kelvin-feld"]-273.15) + 32.0
34 if was != "reaumur-feld":
35 wert["reaumur-feld"] = (4.0/5.0)*(wert["kelvin-feld"]-273.15)
36 if was != "rankine-feld":
37 wert["rankine-feld"] = (9.0/5.0)*wert["kelvin-feld"]
38
39 for i in felder:
40 if was != i:
41 widget[i].handler_block(handler[i])
42 widget[i].set_value(wert[i])
43 widget[i].handler_unblock(handler[i])
44
45 def __init__(self):
46 builder = gtk.Builder()
47 builder.add_from_file("temperatur.gtkbuilder")
48 for i in (("fenster", "schliessknopf") + felder):
49 widget[i] = builder.get_object(i)
50 for i in felder:
51 handler[i] = widget[i].connect("value_changed", self.geaendert, i)
52 widget["schliessknopf"].connect_object("clicked", gtk.Window.destroy, widget["fenster"])
53 widget["fenster"].connect("delete_event", self.delete_event)
54 widget["fenster"].connect("destroy", self.destroy)
55 widget["fenster"].show_all()
56 widget["celsius-feld"].set_value(100)
57
58 def main(self):
59 gtk.main()
60
61 if __name__ == "__main__":
62 app = TemperaturApp()
63 app.main()
Die Methode »main()«
in Zeile 58 startet lediglich die Hauptschleife, »destroy()«
in Zeile 16 beendet diese beim Aufruf, »delete_event()«
in Zeile 13 ist ein Ereignishandler für das Schließen des Programms durch den Fenstermanager und gibt nur »False«
zurück. Die Anwendungslogik steckt in »geaendert()«
ab Zeile 19. Es handelt sich um einen Signalhandler, der aufgerufen wird, wenn eines der Zahlenfelder seinen Wert ändert.
Um so wenig Code wie möglich fünfmal schreiben zu müssen, verwendet der Entwickler das Tupel »felder«
mit den Kennungen aller Zahlenfeld-Widgets in der GTK-Builder-Datei sowie die Dictionaries »wert{}«
, »widget{}«
und »handler{}«
(Zeilen 6 bis 9), die die Widget-Objekte selbst, ihre Werte für die Neuberechnung sowie die Kennungen speichern, unter denen jeweils »geaendert()«
als Signalhandler an sie gebunden ist. Dabei dient das Tupel »felder«
als Indexmenge.
Der Konstruktor »__init__()«
mit dem für den Aufbau des Dialogfensters zuständigen Code ist ab Zeile 45 zu sehen. Er lädt die GTK-Builder-Datei in das Objekt »builder«
und entnimmt daraus mit »get_object()«
die Widgets. So weit wie möglich setzt das Programm For-Schleifen ein, um über die Widgets zu iterieren, etwa beim Binden von »geaendert()«
als Signalhandler an das Signal »value_changed«
der Zahlenfelder in Zeile 51.
Die Methode »geaendert()«
zeigt in den Zeilen 39 bis 43, wozu die Kennungen nützlich sind, die »gtk.Widget.connect()«
beim Binden eines Signalhandlers zurückgibt. Sie lassen sich einsetzen, um eine Endlosschleife zu verhindern: Wenn das Programm den neu berechneten Wert in ein Zahlenfeld schreibt, würde das eigentlich eine Emission des Signals »value-changed«
und damit wiederum eine Neuberechnung auslösen. Daher sperrt der Code vor dem Setzen des Wertes den Signalhandler des betreffenden Felds mit der Widget-Methode »handler_block()«
, hinterher entsperrt er sie mit »handler_unblock()«
wieder.
Linux
Unter Linux läuft das Programm wie erwartet ohne Probleme. Da Ubuntu-Kernkomponenten auf Python und GTK+ basieren, sind die benötigten Pakete »python-gtk2«
und »python-glade2«
samt ihren Abhängigkeiten ohnehin schon installiert. Aufgerufen mit »./temperatur.py«
sieht das Ergebnis aus wie in Abbildung 2.
Diesen Artikel als PDF kaufen
Express-Kauf als PDF
Umfang: 4 Heftseiten
Preis € 0,99
(inkl. 19% MwSt.)
Als digitales Abo
Weitere Produkte im Medialinx Shop »
Versandartikel
Onlineartikel
Alle Rezensionen aus dem Linux-Magazin
- Buecher/07 Bücher über 3-D-Programmierung sowie die Sprache Dart
- Buecher/06 Bücher über Map-Reduce und über die Sprache Erlang
- Buecher/05 Bücher über Scala und über Suchmaschinen-Optimierung
- Buecher/04 Bücher über Metasploit sowie über Erlang/OTP
- Buecher/03 Bücher über die LPI-Level-2-Zertifizierung
- Buecher/02 Bücher über Node.js und über nebenläufige Programmierung
- Buecher/01 Bücher über Linux-HA sowie über PHP-Webprogrammierung
- Buecher/12 Bücher über HTML-5-Apps sowie Computer Vision mit Python
- Buecher/11 Bücher über Statistik sowie über C++-Metaprogrammierung
- Buecher/10 Bücher zu PHP-Webbots sowie zur Emacs-Programmierung
Insecurity Bulletin
Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...





