GUI Designer und User Interface a la picubu?

Fragen zu Tkinter.
Antworten
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

GUI Designer und User Interface a la picubu?

Mein GUI Designer bietet die Funktionalitäten, wofür er gedacht ist, nämlich als GUI Designer für tkinter aber noch nicht für ttk.
Das Widget Canvas kann man zwar positionieren und die Größe bestimmen. Linien oder Polygone zeichnen gehört allerdings nicht zum Umfang meines GUI Designers. Das soll man selber programmieren. Ein Canvas Zusatzmodul wäre allerdings denkbar.
Dafür bietet mein GUI Designer als einziger ein Grid Konzept, wie es das nirgendwo anders gibt. Und das ist etwas, was man sich unbedingt ansehen sollte.

Worum es aber jetzt geht, ist die Frage, wie diverse User Interfaces aussehen sollen.
Im Augenblick ist es so, dass die UI Files (File Extension egal) gleich die GUI inklusive der Widgets aufbauen – und die UI Files auch gleich Programmcode beinhalten können.
Und man hat dann Zugriff auf die Widgets durch eine Zugriffsfunktion. Im Augenblick ist diese auf einen Container beschränkt, aber das läßt sich erweitern.
Was aber gewünscht wird, ist die Verwendung eigener Klassen.

Die Frage ist nun, wie soll man das machen?

Bei Pygubu finden wir folgendes: https://pypi.python.org/pypi/pygubu

Code: Alles auswählen

import pygubu
Das ist klar, ohne etwas Zusätzliches zu importieren geht es nicht.

Was wir dann noch finden, ist einerseits gut, aber andererseits auch schlecht:

Code: Alles auswählen

#1: Create a builder
self.builder = builder = pugubu.Builder()
Gut ist, dass hier eine Instanz erzeugt wird. Das sollte man auch so machen, denn am Ende soll ein geladenes UI File von selber wieder entladen werden.

Schlecht ist, dass das UI File fest mit einem self verknüpft ist, denn man braucht es ja nur kurzzeitig zur Initialisierung der Widgets und kann es vermutlich nach __init__ einfach vergessen.
Allerdings wenn der Builder eigene Klassen beinhaltet, würde man ihn während der ganzen Lebenszeit des Objektes brauchen.
Meine Meinung dazu ist, dass tkinter widgets vom Builder erzeugt werden sollen oder User Klassen initialisiert werden sollen. Und dass der Builder daher nach der Erzeugung überflüssig werden sollte.

Kommen wir zum nächsten TeiL:

Code: Alles auswählen

#2: Load an ui file
builder.add_from_file('test.ui')
Hier heißt es add. Anscheinend kann man gleich auf mehrere UI Files gleichzeitig zugreifen, wenn man noch ein weiteres add macht. Aber ist das nötig? Das könnte leicht eine Namenskollision geben.

Danach wird das widget erzeugt:

Code: Alles auswählen

#3: Create the widget using a master as parent
self.mainwindow = builder.get_object('mainwindow', master)
Das ist eine Erzeugungsart, die man auf jeden Fall anbieten muss. Aber diese Art der Erzeugung reicht nicht.
Der User könnte ja auch eigene Klassen verwenden wollen und ist dann mit einem tkinter Widget nicht zufrieden. Daher ist dann auch die folgende Art der Widget Erzeugung anzubieten:

Code: Alles auswählen

self.myButton = MyButtonClass(parent)
builder.set_object(self.myButton,'myBuilderButton')
Über Benennungen mag man sich streiten. Aber einverstanden mit dem Prinzip?
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Wollte nur noch dazu bemerken, nötig wären ja eigene Klassen nicht. Denn DynTkInter widgets haben eine Membervariable mydata und da kann man ja ein Objekt kreuzgekoppelt hinhängen, etwa:

widget('mywidget').mydata = MyClass(widget('mywidget'))

Zugeben muss ich allerdings, dass das nicht reicht, wenn man Widget Methoden, wie grid, pack oder place überschreiben will.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

GUI Interface a la picubu, denke ich, macht nicht viel Sinn.
Denn warum soll man eine GUI, die man eh schon hat, nochmal nachprogrammieren?

Sinnvoller ist da, die Access Funktion 'widget' noch ein wenig zu erweitern.
'widget' greift zur Zeit nur auf Widgets im ausgewählten Container zu.

Angenommen, wir sind in einer 'Stadt' in einer 'Straße' in einem 'Haus' in einer 'Wohnung' im 'Schlafzimmer' im 'Schrank' und wollen einen 'Mantel' auswählen,
dann müssen wir zuerst bis in den Schrank gehen, damit wir ihn mit widget('Mantel') auswählen können.

Aber wenn wir implementieren, dass der erste Parameter auch etwas anderes als ein String sein kann und wir das dann unterschiedlich behandeln, könnten wir gleich auswählen:

Code: Alles auswählen

widget(access.Schlafzimmerschrank,'Mantel')
Und das access Objekt könnten wir zur GUI laden.
Und der GUI Designer könnte es abspeichern, sofern wir diesen Menüpunkt aufnehmen.
Antworten