Struktur einer GUI

Fragen zu Tkinter.
Antworten
Mesta
User
Beiträge: 10
Registriert: Donnerstag 16. August 2018, 10:40

Hallo zusammen,

ich bin jetzt schon länger am rätseln wie ich eine etwas komplexere GUI am besten strukturiere.

Zuerst einmal zu meiner Grundstruktur:

Code: Alles auswählen

class MainGui(Tk):

    def __init__(self):
        super().__init__()
        self.menu_window = MainWindow(self)


class MainWindow(Frame):

    def __init__(self, root):
        super().__init__()
        self.root = root
        self.initObj() #Factory für gebraucht Klassen
        self.initUi() #Weitere Aufteilung des Frames

    def initUi(self):
        menu_bar = MenuBar(self.master) #init der Menüleiste, jeweils gebrauchte Objekte werden noch übergeben
        tool_bar = ToolBar(self.master) #init der Toolleiste, ebenso übergabe der Objekte
	#usw.
Für die einzelnen Funktionen stehen jeweils Klassen zur verfügung die ich in der MainWindow-Klasse erzeuge, außerdem habe ich für die Buttons etc. (z.B. für die Tool-Leiste) Klassen erzeugt von denen ich jeweils Unterklassen bilde.
Mein problem ist, dass der Code so langsam unübersichtlich wird. Für jede neue Funktion muss ich an etlichen stellen Parameter/Objekte übergeben und die Erweiterung wird immer schwerer.
Meine Frage wäre, was für eine GUI die "normale/sauberste"-Struktur wäre?
Sollte man eine Struktur in XML o.ä. anlegen und diese einlesen (bin ich gerade bei), oder eher eine Datenbank in der die Struktur übernommen wird (Aber wo werden dann die aufgerufenen Klassen erzeugt)?

Ich habe mir schon einige GUI-Tutorials durchgelesen, aber die gehen meistens nicht auf komplexere Strukturen ein.
Für nützliche Tipps oder passende Links währe ich sehr dankbar.

Grüße
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich wuerde zuerstmal in Frage stellen, das du Ableitungen fuer irgendwelche Buttons brauchst. Gerade tkinter kennt ja nur beschraenkt viele Moeglichkeiten, das look und feel seiner Elemente durch Ableitung zu beeinflussen. Und nur, weil man dann im __init__ gleich ein configure aufruft, das da irgendwas setzt, ist das auch nicht notwending.

Mein Ansatz, um dem Chaos etwas entgegen zu setzen: trenn die Erzeugung des GUI-Baums von der Benutzung mit deiner Applikations-Logik. Das entspricht in etwa dem, was der Qt-Designer mit seiner XML-basierten .ui-Files schon macht, und was dann mit pyuic benutzt wird. Da tkinter keinen Mechanismus hat, mit dem man auf den Widget-Tree per Namen einzelner Elemente zugreifen kann, musst du das selbst machen. Also in Pseudo-Code:

Code: Alles auswählen

def create_gui(root):
      elements = {}
      f1 = Frame(root) # "schlechter" Name, weil nur strukturierungs-Element.
      b = elements["wichtiger-button"] = Button(f1) # auf den willst du spaeter zugreifen, der muss raus gegeben werden
      b.configure(...)
      return elements
An der Stelle, wo du create_gui aufrufst, kannst du dann mit den in elements referenzierten Widgets arbeiten, und da zB das command rankonfigurieren.

Was ich genau NICHT machen wuerde ist fuer diese Widget-Hierarchie XML einzusetzen! Das ist ein typisches Yak-Projekt, bei dem du viel Zeit und Muehe darauf verwendest, eine pseudo-Programmiersprache zu basteln, die du mit Python und seiner klaren, simplen Syntax schon hast.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Vielleicht käme ja auch ein anderes GUI-Rahmenwerk in Frage? Tk ist da ja nicht mehr wirklich auf der Höhe der Zeit was Konzepte zur Unterstützung von komplexeren Anwendungen angeht. Für kleine, einfache GUIs ist das ganz nett, aber wenn man auf solche Probleme stösst, die in modernen Rahmenwerken bereits Lösungen haben, muss man abwägen ob man diese Lösungen jetzt wirklich selber, wahrscheinlich in schlechter, noch mal für Tk nachprogrammieren möchte, oder ob man die Zeit nicht besser in einen Umstieg investiert. Sowohl Qt als auch Gtk haben jeweils einen grafischen Designer der Datendateien erstellt, die man dann zur Laufzeit laden kann.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Mesta
User
Beiträge: 10
Registriert: Donnerstag 16. August 2018, 10:40

@__deets__
Ok, danke das werde ich mal ausprobieren, nur das dann evtl Spaghetticode entsteht, aber man kann es ja in sinnvolle Methoden verpacken, mal schauen.

@__blackjack__
Ich wollte zuerst PyQt verwenden, nur fand ich das konzept mit der kommerziellen Version nicht passend für mich. GTK+ werd ich mir nochmal genauer anschauen, wenn etwas Zeit dafür da ist.
Mesta
User
Beiträge: 10
Registriert: Donnerstag 16. August 2018, 10:40

Tkinter erstellt auch automatisch eine Widget-Struktur auf die man später zugreifen kann.

Code: Alles auswählen

#... 
	button = Button(root, name='ein_button')
#...
	
#button auswählen
ein_button = root.nametowidget('.frame.ein_button')
ein_button.command('...')
#usw.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mesta: Naja, aber dann baut man eine parallele Struktur auf und muss auch noch zweimal Namen vergeben. Und das macht in Python so sonst niemand.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Mesta
User
Beiträge: 10
Registriert: Donnerstag 16. August 2018, 10:40

Wenn man nur diese Struktur verwendet muss man nur einmal Namen vergeben. Ich habe zuerst ein Dictonary, wie __deets__ oben empfohlen hat, erstellt und dann bemerkt das Tk von Haus aus schon eine hierarchische Struktur erstellt, was allerdings nicht nötig gewesen wäre.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mesta: Aber wenn man dann mal die Widgets anders anordnet in der Hierarchie, dann muss man überall im Programm den Tk-Widget-Pfad anpassen. Stelle ich mir unpraktisch vor.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Mesta
User
Beiträge: 10
Registriert: Donnerstag 16. August 2018, 10:40

Hm, ja stimmt. Idealerweise sollte das ja nicht passieren, aber wer weis.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Genau das passiert andauernd, weil man aus Layout-Gruenden Dinge zB ein Frames packt etc.
Antworten