alan hat geschrieben:Wie trennt man Programmlogik und GUI am besten?
Hallo alan!
Ich kann dir kein "am besten"-Rezept geben. Ich kann dir nur aufzeigen, wie ich es in meinen Programmen mache.
Es gibt meistens zwei Module. Ein Modul mit dem Programm und ein Modul mit der GUI dazu. Im Programmmodul, ich nenne es einfach mal Hauptmodul, lese ich die Kommandozeilenparameter und die zum Programm gehörenden INI-Dateien aus. Diese Einstellungen/Optionen (wie auch immer), stelle ich in einem globalen "Settings"-Objekt zur Verfügung. Noch bevor ich die Einstellungen einlese, kümmere ich mich darum, dass ein Objekt für das Logging zur Verfügung steht.
Das sieht dann in etwa so aus:
Code: Alles auswählen
class Log(logging.RootLogger):
"""
Stark angepasster RootLogger. Loggt die Meldungen in die Datei
GLOBAL_LOGFILE und gibt die Logmeldungen auch im Konsolenfenster aus.
"""
...
# Globales Logging
log = Log()
class Settings(object):
"""
Einstellungen
Liest die INI-Datei(en) aus und kann die Einstellungen zusätzlich auch
aus der Kommandozeile parsen. Standardeinstellungen sind in einem Dictionary
vorgegeben. Es macht also nichts, wenn die gewünschte Einstellung nicht in
einer INI-Datei und auch nicht in der Kommandozeile steht.
"""
...
# Globale Einstellungen
settings = Settings()
Natürlich gibt es im Hauptmodul noch eine *main()*-Funktion und für viele Fälle noch eigene Klassen, die z.B. für den Datenbankzugriff, Berechnungen usw. zuständig sind.
Dieses Modul kann direkt aufgerufen werden. Und meist kann man über Kommandozeilenparameter (Optione, Argumente) dem Programm Aufgaben übergeben, die es ohne GUI erledigen kann. Z.B. könnte man als Kommandozeilenoption das Gewicht, die Größe und das Alter übergeben und diese Daten, mit dem aktuellen Datum, versehen in eine Datenbank schreiben lassen.
Statt die oben genannten Daten in die Konsole eingeben zu lassen, könnte man jetzt ein zusätzliches GUI-Modul zur Eingabe in ein GUI-Fenster mit ein paar Textfeldern schreiben. Dieses GUI-Modul **importiert** nun das Hauptmodul und stellt zusätzlich ein Fenster für die Eingabe zur Verfügung.
Vorteil! Die Einstellungen werden automatisch, beim Importieren des Hauptmodules, eingelesen und sind über die Referenz zum Hauptmodul verfügbar. Das betrifft die Kommandozeilenoptionen und die INI-Dateien.
Der Nachteil bei diesem Vorgehen ist der, dass man Einstellungen, die nur die GUI betreffen, ins Hauptmodul einbauen muss. Das ist bei mir aber so selten der Fall, dass es mich auch nicht sonderlich stört, wenn in der INI-Datei auch die Einstellungen für die GUI stehen. Die Fenstergröße und Fensterpositon speichere ich sowiso in eigene INI-Dateien. Das macht jede Klasse automatisch, die von *AutoSizeSave* und *AutoPositionSave* erben. Siehe:
http://www.python-forum.de/topic-9701.html
So kann ich mehrere kleine GUI-Programme machen, die jeweils eine Aufgabe für sich erfüllen. Ich kann damit aber auch eine große GUI schreiben. Ein GUI, mit dem man alle Programmfunktionen bedienen kann. -- Einfach wieder vom neuen GUI-Programmmodul aus das Hauptmodul importieren und los legen.
Die kleinen GUI-Progrämmchen könnte man so schreiben, dass diese auch von einem großen GUI-Programmmodul importiert werden können. So könnte man z.B. vom Haupt-GUI-Programm aus das Modul zum Eingeben der Größe, dem Gewicht, usw. importieren und den Dialog direkt aufrufen.
Also so mache ich es.
mfg
Gerold
