Sirius3 hat geschrieben:Man kann das so schreiben, aber das hat genauso wenig Sinn, wie den ganzen anderen Quatsch, den Du hier schreibst und ihn als unumstößliche Wahrheit anpreist. Wenn Du keine Ahnung hast, kannst Du gerne Fragen, aber hör auf damit, Deine kruden Ansichten Anfängern als Lösungen unterzujubeln.
Es macht total viel Sinn, statt viele Klassen in einem Script zu haben, etliche Module zu haben. Statt lang in einem großen Script zu suchen, erinnert man sich meist an den Dateinamen für die GUI Komponente. Und in dieser Datei ist man von vielem anderem Code der nicht dazugehört, nicht abgelenkt und kommt auch nicht auf die Idee irgendwelche Querverweise auf anderes zu implementieren.
Solche Module sind sehr übersichtlich. Ich habe einmal das Programm in Module aufgeteilt:
Code: Alles auswählen
# === GUI Applikation ====
application.py
- application_gui.py
- - lift_frame_gui.py
- - - remote_manager_gui.py
- - - page_one_gui.py
- - - page_two_gui.py
- main_menu_gui.py
- - manager_menu_gui.py
- - hilfe_menu_gui.py
# === Helper Modules =====
tk.py
eventbroker.py
Im Dateimanager kann man seine Module leicht finden - ab alphabetisch oder nach Änderungsdatum. Wer will kann auch den Aufbau, wie oben dargestellt, noch dokumentieren. Ich habe das aber nicht gebraucht, weil man sich doch an die Filenamen erinnert und der Aufbau genaugenommen keine Rolle spielt.
Kommen wir zu den Helper Modulen. Wenn man so etwas hat wie tk.py braucht man nicht immer zwischen tkinter und Tkinter zu unterscheiden, auch läßt sich leicht DynTkInter einbinden.
Ein sehr einfaches Modul ist
tk.py:
Code: Alles auswählen
try:
from tkinter import *
except ImportError:
from Tkinter import *
Dann sollte auch dabei sein
eventbroker.py:
Code: Alles auswählen
class EventBroker():
def __init__(self):
self._dictionary_ = {}
def subscribe(self,message_id,callback):
self._dictionary_[message_id] = callback
def publish(self,message_id,*args,**kwargs):
self._dictionary_[message_id](*args,**kwargs)
eventbroker = EventBroker()
publish = eventbroker.publish
subscribe = eventbroker.subscribe
Das ist aber nur die simpelste Ausführung. Aber sicher leicht zu begreifen.
Da man darauf besteht, daß man zuerst sein Programm startet und dann erst die GUI nachlädt, hatt man dann ein Script File.
application.py
Code: Alles auswählen
import tk
import application_gui
def main():
root = tk.Tk()
application_gui.init(root)
# eigener Code
root.mainloop()
main()
Da lädt man dann die GUI und will anscheinend hinterher noch etwas machen.
Das ist dann die GUI.
application_gui.py
Code: Alles auswählen
import tk
import lift_frame_gui
import main_menu_gui
def init(self):
# GUI ==============================
lift_frame = tk.Frame(self,name='lift_frame')
main_menu = tk.Menu(self,name='main_menu')
self['menu'] = main_menu
lift_frame.pack(fill='both', expand=1)
lift_frame_gui.init(lift_frame)
main_menu_gui.init(main_menu)
# END GUI ===========================
Das ist doch sehr übersichtlich. Und man kann sich jetzt auf zusätzliche Codierung konzentrieren. Aber offensichtlich gibt es da nichts zu tun.
Das dürfe bei diesem lift_frame aber anders werden.
lift_frame_gui.py
Code: Alles auswählen
import tk
import remote_manager_gui
import page_one_gui
import page_two_gui
from eventbroker import subscribe,publish
def init(self):
# GUI ==============================
self.rowconfigure(0,weight=1)
self.columnconfigure(0,weight=1)
remote_manager = tk.Frame(self,name='remote_manager')
page_one = tk.Frame(self,name='page_one')
page_two = tk.Frame(self,name='page_two')
remote_manager.grid(row=0,sticky = 'nsew')
page_one.grid(row=0,sticky = 'nsew')
page_two.grid(row=0,sticky = 'nsew')
remote_manager_gui.init(remote_manager)
page_one_gui.init(page_one)
page_two_gui.init(page_two)
# END GUI ===========================
# CODE ==============================
frames = {'remote_manager' : remote_manager,
'page_one' : page_one,
'page_two' : page_two,
}
subscribe('SHOW_FRAME',lambda frame_id, frames = frames: frames[frame_id].lift())
publish('SHOW_FRAME','remote_manager')
# END CODE ==========================
Das ist das Kernstück der Applikation. Man hat drei Frames in einer einzigen grid Zelle und will auf Anforderung den einen oder anderen in den Vordergrund rücken und damit sichtbar machen.
Erreicht wird dies dadurch, dass diese Frames mit einer ID in einem Dictionary erfasst werden. Dafür gibt es einen Message Callback, mit dem eine Funktion aufgerufen wird, die dann den entsprechenden Frame liftet. Diese Funktion ist das lambda im subscribe Callback.
Dann hat man diese drei Frames, die sich auch auf Buttondruck gegenseitig liften. Der Code Part dazu ist relativ einfach.
remote_manager_gui.py
Code: Alles auswählen
import tk
from eventbroker import publish
from functools import partial
def init(self):
# GUI ==============================
label =tk.Label(self,text='Willkommen im Remote Manager')
button_page_one = tk.Button(self,name='button_page_one',text='Benutzereinstellungen', width=18)
label_2 = tk.Label(self)
button_2 = tk.Button(self,text='Bildschirmeinstellungen', width=18)
label_3 = tk.Label(self)
button_page_two = tk.Button(self,name='button_page_two',text='Servereinstellungen', width=18)
label_4 = tk.Label(self)
label.pack(pady=15, padx=25)
button_page_one.pack()
label_2.pack(pady=1, padx=25)
button_2.pack()
label_3.pack(pady=1, padx=25)
button_page_two.pack()
label_4.pack(pady=5, padx=25)
# END GUI ===========================
# CODE ==============================
button_page_one.config(command=partial(publish,'SHOW_FRAME','page_one'))
button_page_two.config(command=partial(publish,'SHOW_FRAME','page_two'))
# END CODE ==========================
page_one_gui.py
Code: Alles auswählen
import tk
from eventbroker import publish
from functools import partial
def init(self):
# GUI ==============================
label = tk.Label(self,text='Page One!!!', font='Verdana 12')
button_remote_manager = tk.Button(self,name = 'button_remote_manager',text='Back to Home')
button_page_two = tk.Button(self,name='button_page_two',text='Page Two')
label.pack(pady=20, padx=10)
button_remote_manager.pack()
button_page_two.pack()
# END GUI ===========================
# CODE ==============================
button_remote_manager.config(command=partial(publish,'SHOW_FRAME','remote_manager'))
button_page_two.config(command=partial(publish,'SHOW_FRAME','page_two'))
# END CODE ==========================
page_two_gui.py
Code: Alles auswählen
import tk
from eventbroker import publish
from functools import partial
def init(self):
# GUI ==============================
label = tk.Label(self,text='Page Two!!!', font='Verdana 12')
button_remote_manager = tk.Button(self,name = 'button_remote_manager',text='Back to Home')
button_page_one = tk.Button(self,name='button_page_one',text='Page One')
label.pack(pady=10, padx=10)
button_remote_manager.pack()
button_page_one.pack()
# END GUI ===========================
# CODE ==============================
button_remote_manager.config(command=partial(publish,'SHOW_FRAME','remote_manager'))
button_page_one.config(command=partial(publish,'SHOW_FRAME','page_one'))
# END CODE ==========================
Dann hat man noch das Menü.
main_menu_gui.py
Code: Alles auswählen
import tk
import manager_menu_gui
import hilfe_menu_gui
def init(self):
# GUI ==============================
manager_menu = tk.Menu(self,name='manager_menu')
hilfe_menu = tk.Menu(self,name='hilfe_menu')
self.add_cascade(menu=manager_menu,label='Manager')
self.add_cascade(menu=hilfe_menu,label='Hilfe')
manager_menu_gui.init(manager_menu)
hilfe_menu_gui.init(hilfe_menu)
# END GUI ===========================
Es hat zwei Untermenüs und dafür auch zwei Cascaden
Das ist dann das Untermenü mit viel Action.
manager_menu_gui.py
Code: Alles auswählen
from functools import partial
from eventbroker import publish
def init(self):
# GUI ==============================
self.config(tearoff=0)
self.add_command(label='Komplettes Setup')
self.add_separator()
self.add_command(label='Benutzereinstellungen')
self.add_command(label='Bildschirmeinstellungen')
self.add_command(label='Servereinstellungen')
self.add_separator()
self.add_command(label='Beenden')
remote_manager_index = 0
page_one_index = 2
page_two_index = 4
# END GUI ===========================
# CODE ==============================
self.entryconfig(remote_manager_index,command=partial(publish,'SHOW_FRAME','remote_manager'))
self.entryconfig(page_one_index,command=partial(publish,'SHOW_FRAME','page_one'))
self.entryconfig(page_two_index,command=partial(publish,'SHOW_FRAME','page_two'))
# END CODE ==========================
Aber beim anderen tut sich noch nicht viel.
hilfe_menu_gui.py
Code: Alles auswählen
def init(self):
# GUI ==============================
self.config(tearoff=0)
self.add_command(label='Info')
# END GUI ===========================
Ist doch alles schön übersichtlich und ganz ohne Klassen.
Ach so das war es auch schon, denn in application.py war doch nichts zu tun.