tkinter GUI Designer

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

jens hat geschrieben:
Alfons Mittelmeyer hat geschrieben:Hier wird nichts geladen, sondern das Widget ist da.
Und wo bzw. wie wird ein Widget zusammen gesetzt?!?
Du meinst, wie man das Widget im GUI Designer zusammenstellt?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ja, das ist doch der Kern eines GUI Designers...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: ich vermute, Du baust wieder einmal zu viel Magie um Dinge, die Python sowieso schon von sich aus kann. Aber ohne Code, kann ich nur vermuten:

Wenn Du ein verschachteltes Layout hast, würde ich das genau so in einem Baum abbilden:

Code: Alles auswählen

gui = load_widgets('mygui.json')
[...]
myX_Spinbox = gui.CreateAndLayout.LayoutShort.LayoutShortShowHide.PlaceLayout.X
Natürlich will das niemand so schreiben, aber irgendwo hat man ja schon den Parent:

Code: Alles auswählen

myX_Spinbox = parent.X
Das mit den abgeleiteten Klassen ist meiner Meinung nach auch zu kompliziert gedacht. Abgeleitete Klassen werden einfach vor dem Laden der GUI registriert:

Code: Alles auswählen

register_widget('MyButton', MyButton)
gui = load_widgets('mygui.json')
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

jens hat geschrieben:Ja, das ist doch der Kern eines GUI Designers...
Bräuchte einen Bilder Paste Dienst. Weiss aber keinen. Auf google Drive hatte ich unter Android ein gif geladen. Kann das aber unter Linux nicht ansehen: https://drive.google.com/file/d/0Bwsrqx ... sp=sharing
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:@Alfons Mittelmeyer: ich vermute, Du baust wieder einmal zu viel Magie um Dinge, die Python sowieso schon von sich aus kann. Aber ohne Code, kann ich nur vermuten:

Wenn Du ein verschachteltes Layout hast, würde ich das genau so in einem Baum abbilden:

Code: Alles auswählen

gui = load_widgets('mygui.json')
[...]
myX_Spinbox = gui.CreateAndLayout.LayoutShort.LayoutShortShowHide.PlaceLayout.X
Das kann man so nicht machen. Das ist ja so eine Art von Klassenbaum. Und wie löscht man da Verzeichnisse aus der Klasse wieder heraus? Etwa mit del? Das Prinzip ist ja Dynamik mit Hinzuladen von Teilen und Löschen von Teilen
Sirius3 hat geschrieben:Das mit den abgeleiteten Klassen ist meiner Meinung nach auch zu kompliziert gedacht. Abgeleitete Klassen werden einfach vor dem Laden der GUI registriert:

Code: Alles auswählen

register_widget('MyButton', MyButton)
gui = load_widgets('mygui.json')
Das muss ich mir noch überlegen wie das gemeint ist. Das sieht ja nach globalen Namen aus. Wäre natürlich auch machbar. Bei komplexer GUI mit vielen Elementen und Dazuladen und Löschen, kommt man aber mit globalen Namen bald ins Schleudern. Ach so, es sind Klassen und keine Widgets. Blick noch nicht recht durch.
Zuletzt geändert von Alfons Mittelmeyer am Donnerstag 27. August 2015, 11:33, insgesamt 1-mal geändert.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Alfons Mittelmeyer hat geschrieben:
jens hat geschrieben:Ja, das ist doch der Kern eines GUI Designers...
Bräuchte einen Bilder Paste Dienst. Weiss aber keinen. Auf google Drive hatte ich unter Android ein gif geladen. Kann das aber unter Linux nicht ansehen: https://drive.google.com/file/d/0Bwsrqx ... sp=sharing
https://startpage.com/do/search?query=image+paste :P

z.B.: http://snag.gy/

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@jens Danke. So sieht der GuiDesigner zur Zeit aus. Professionelles Design ist es wohl nicht.
Bild

Hier ist im Layout grid der grüne Button grid ausgewähl. Das Pack Layout ist nicht zu sehen, weil Pack und Grid sich nicht vertragen. Grid und Place gemischt macht wohl auch wenig Sinn, aber zumindest gibt es dabei keinen Systemabsturz.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das sieht so aus, als wenn man doch wieder ziemlich viel per Hand zusammenstellen muß...

Also nix mit WYSIWYG, oder?

Kann man vielleicht ein wenig mit Web-Design vergleichen (auch wenn man dort nicht mehr mit Tabellen zum Layouten hantiert): Ich will halt bei einer Tabelle, die Sachen einfach per Drag&Drop hin und her schieben können. Hier eine Spalte hinzufügen, dort eine Zeile löschen usw.
Aber nix mit Zahlen eingeben: Wie viele Spalten sollen denn angelegt werden? In welcher Zeile/Spalte soll den das GUI Element landen?!?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

jens hat geschrieben:Das sieht so aus, als wenn man doch wieder ziemlich viel per Hand zusammenstellen muß...

Also nix mit WYSIWYG, oder?

Kann man vielleicht ein wenig mit Web-Design vergleichen (auch wenn man dort nicht mehr mit Tabellen zum Layouten hantiert): Ich will halt bei einer Tabelle, die Sachen einfach per Drag&Drop hin und her schieben können. Hier eine Spalte hinzufügen, dort eine Zeile löschen usw.
Aber nix mit Zahlen eingeben: Wie viele Spalten sollen denn angelegt werden? In welcher Zeile/Spalte soll den das GUI Element landen?!?
Per Hand muß man nicht viel machen. Das Hin und Herschieben gibt es beim Place Layout. Wenn man auf place at 0,0 drückt, hat man das Element in der oberen linken Ecke und zieht es mit der Maus. Außerdem werden dann auch per Mausdruck die Elemente ausgewählt.

Beim Grid Layout könnte ich das auch implementieren. Trotzdem geht beim Gridlayout auch ewas automatisch. Angenomment Du hast das:

Name
Vorname
Tel
PLZ
Ort
Strasse

Dann kreuzt Du die Checkbox inc hinter row an. Wenn Du dann ein widget mit 'grid' plaziert hast, geht automatisch der row Zähler hoch und das nächste Widget landet dann darunter. Und wenn Du mit der Strasse durch bist, drückst Du auf 'new row'. Dann springen die Angaben um auf col=1 und row=0 und dann gibst Du die Entry Felder ein. Wenn Du mehr brauchst, dann ist das ein Feature Wunsch. Und wenn das gebraucht wird, dann wird es eben implementiert. Ist ja kein großes Problem. Aber eine Tabelle sollte natürlich dynamisch programmiert sein. Etwa erste Zeile ausprobieren, wie es aussieht und dann die Zeilen dynamisch anlegen.

Also zusätzliche Features stellst Du Dir vor: Spalte einfügen, Spalte löschen, Zeile einfügen, Zeile löschen. Klingt sinnvoll. Müsste man nur überlegen, wie das aussehen soll. Mit der Maus wäre ein wenig problematisch. Neue Spalten in denen noch nichts ist, haben die Breite 0. Sieht man also nichts.

Und bei den Eingaben beim Place Layout könnte man denken, dass man damit händisch platzieren muss. Nö, am geschicktesten platziert man mit der Maus. Damit danach die Objekte exakt in einem Raster angeordnet sind, drückt man danach 'Adjust'. Das gibt dann ein Vielfaches von dem was in incx bzw. incy steht. Und war es dann um einen Schritt daneben, dann nimmt man x oder y und zwar die Spinbox Buttons. Die zählen dann auch in der rechts davon angegebenen Schrittweite hoch oder runter.

Damit aber die Elemente genau passen, darf man nicht anchor auf nw nehmen. Empfehlenswert für Labels vor einem Entry wäre anchor e und für die Entrys anchor w.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

place würde ich komplett raus nehmen.

Tabellen mit der Maus editieren ist so eine Sache. Gibt es verschiedene Ansätze und Beispiele.
Kompliziert wird es dann, wenn man verschachtelt.

Aber WYSIWYG ist das was ein visueller GUI Editor können sollte. Ansonsten kann man auch gleich Code selbst schreiben.


Wie schon öfters gesagt: Schau dir halt mal existierende Lösungen an.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

[quote="Sirius3"]Das mit den abgeleiteten Klassen ist meiner Meinung nach auch zu kompliziert gedacht. Abgeleitete Klassen werden einfach vor dem Laden der GUI registriert:

Code: Alles auswählen

register_widget('MyButton', MyButton)
Ja, das mit den Klassen könnte man so machen, dass der GUI Designer, nicht nur 12 tkinter Klassen kann, sondern man beliebige abgeleitete Klassen auch eingeben kann. Hatte ich mir auch schon überlegt. Wäre nur die Frage, wie eine Eingabe für 50 weitere Klassen oder ähnlich aussehen könnte. Könnte man unter config options erfassen. Wäre zu überlegen. Allerdings eine Kontrolle hat man dann bei der GUI Erfassung nicht, wenn man sich dabei vertippt. Eine Zeile würde man dann im Code sparen, nämlich:

Code: Alles auswählen

# statt
mybutton=MyButton(parent)
gui.set_attributes(mybutton,'myButton',parent)

# nur
mybutton=gui.get_widget('myButton',parent)
Naja könnte man beides anbieten. Schreibt man 'dummy' rein, wenn es diie erste Art sein soll, und etwas anderes, wenn es ein Klassenname sein soll. Und sollte man noch eine Funktion zur Verfügung stellen, die checkt, ob alle Klassen aufgelöst wurden, damit man weiß, ob man sich vertippt hat.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

jens hat geschrieben:Das sieht so aus, als wenn man doch wieder ziemlich viel per Hand zusammenstellen muß...

Also nix mit WYSIWYG, oder?

Kann man vielleicht ein wenig mit Web-Design vergleichen (auch wenn man dort nicht mehr mit Tabellen zum Layouten hantiert): Ich will halt bei einer Tabelle, die Sachen einfach per Drag&Drop hin und her schieben können. Hier eine Spalte hinzufügen, dort eine Zeile löschen usw.
Aber nix mit Zahlen eingeben: Wie viele Spalten sollen denn angelegt werden? In welcher Zeile/Spalte soll den das GUI Element landen?!?
Also mit Zeile/Spalte löschen und einfügen habe ich noch etwas hineingequetscht:
Bild
Ist aber noch nicht implementiert
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das sieht nicht sehr intuitiv aus ;)

Ich erwarte da Punkte im Kontextmenü für.

Schon mal in einer Textverarbeitung eine Tabelle eingefügt und mit rum hantiert?!?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

jens hat geschrieben:Das sieht nicht sehr intuitiv aus ;)

Ich erwarte da Punkte im Kontextmenü für.

Schon mal in einer Textverarbeitung eine Tabelle eingefügt und mit rum hantiert?!?
Ich weiß, dass ich das Grid Layout mit mehr Optionen versehen könnte, was ich etwa beim Place Layout getan hatte. Und die letzte Zeile für Einfügen uind Löschen ist Schmarrn. Da nimmt man besser vier Buttons.

Schaut doch sehr intuiiv aus. Wenn Du ein Widget hast und möchtest es auf grid Position row = 0, column = 0 setzen, dann trägst Du einfach 0 in row und 0 in column ein und drückst jeweils Enter. Und bei einer anderen Position machst Du es genauso. Wenn Du mehrere nebeneinander in einer Zeile hintereinander positionieren willst, dann kreuzt Du die Checkbox (darunter steht inc) hinter dem Entry Eintrag col an und brauchst danach nur immer den Button 'grid' zu drücken. Wenn Du dann in die nächste Zeile wechseln willst, dann drückst Du new row.

Und es ist selbstverständlich 100 % WYSIWYG, denn nachdem Du das gemacht hast, siehst Du das Widget genau da, wo es hingehört. Natürlich könnte man sich eine etwas bessere Bedienung, etwa auch mit Maus wünschen. Dazu kommen wir nachher.

Zu Textverarbeitung und Tabelle. Ich habe nur die tkinter Befehle grid() und grid(row = x, coumn = y) im Basis Grid Layout relisiert. Wahrscheinlich denkst Du, wenn Du von Tabelle sprichst auch an grid_columnconfigure und grid_rowconfigure. Muss man sich nur überlegen, wo und wie man das in der GUI einbaut.

Dann zur Bedienung mit der Maus. Im Place Layout habe ich Bedienung mit der Maus realisiert. Sollte man im Grid Layout wohl auch tun, aber die Fehler wie beim Place Layout vermeiden und sie im Place Layout beseitigen.

Beim Place Layout hatte ich die Bedienung mit der Maus jeweils nur für einzelne Widgets ein oder ausgeschaltet und dann mit geänderten Cursor 'mouse' mir von den Widgets anzeigen lassen, ob sie mit der Maus selektiert und bewegt werden können. Das hat mich aber öfter genervt. Wenn man nachher die GUI gespeichert hatte und vergessen hatte die Mausbedienung wieder auszuschalten, dann wurden die Widgets mit cursor='mouse' gespeichert.

Mein Vorschlag ist:
- den Maus Cursor normal lassen
- auch weiterhin nicht automatisch die Mausbedienung einschalten. Denn Widgets könnten ja bereits mit Maus Events versehen sein, die man nicht automatisch beseitigen möchte.
- Auf Buttondruck alle Widgets in dem betreffenden Container mit dem betreffenden Layout mit Mausbedienung zu versehen.
- Statt zwei Buttons nur einen einzigen Switch Button zu nehmen. An dessen Text und Farbe sieht man dann, ob die Mausbedienung ein oder aus ist.
- Auf Buttondruck dann die Mausbedienung auch wieder für alle Widget ausschalten.
- Im Grid Layout vorerst die Widget Selektion mit der Maus implementieren. Dann ist auch Zeilen oder Spalten einfügen oder löschen einfach. Jetzt muss man entweder die entsprechende Zeile oder Spalte händisch eingeben oder in der Selektion nach einem Widget mit betreffenden Namen suchen, das die passenden row column Koordinaten hat. Einfach auf ein Widget in der betreffenden Zeile oder Spalte klicken und danach Zeile oder Spalte einfügen oder löschen drücken, ist wohl am Einfachsten.
- Überlegen, wie man einzelne Widgets mit der Maus in eine andere Zeile oder Spalte verschiebt. Wie wäre es bei soundsoviel Pixel X.Y Abweichung der Maus relativ zum Beginn, aber nur um eine Spalte oder Zeile?

Und Kontext Menü kommt später, muss mich noch mit PanedWindow und Menü auseinandersetzen.

Und per Container für Grid eine Column Configure Tabelle und eine Row Configure Tabelle, wäre doch etwas aufwändig. Würde ich mir gerne bei der ersten GUI Designer Version ersparen. Setz doch einfach Widgets rein, die genug hoch oder breit sind. Etwas für Spalten in die erste Zeile Frames mit entsprechender Breite aber Höhe 0. Und bei den Zeilen machst Du es auch so.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

jens hat geschrieben:https://github.com/alejandroautalan/pygubu mal angesehen?
Hab mir mal dieses Video angeschaut: https://www.youtube.com/watch?v=wuzV9P8geDg
Das Design links mit dem Menü wirkt professioneller. Die Eingaben wurden gemacht, wie bei mir auch. Diese Listboxen biete ich auch. Das sind die Buttons mit dem Fragezeichen. Anscheinend könnte man auch die Widgets mit der Maus größer ziehen. Kann ich mal irgendwann machen. Den commamd kann man auch in der GUI binden. Geht auf Application.command_function. Aber das ist keine besonders gute Idee. Schränkt die Flexibilität ein. Die Funktion gui.get_widget ist genau die Gleiche, heißt dort builder.get_object. Aber alles in allem, gehen komplexe GUIs dort nicht. Und echt WYSIWYG - bei mir ist es tkinter Original - ist es auch nicht.

Was bestimmt nicht geht. Ich habe zwei zusätzliche Widgets: LinkLabel und LinkButton. Wenn man da draufdrückt, dann wird der Inhalt des betreffenden Containers gelöscht - etwa Frame - und dort etwas Neues nachgeladen. Die Frage ist nur, wie Ihr mit Eurer Art der Programmierung damit umgehen würdet.

Außerdem enthält der GUI Designer Möglichkeiten, ein langes Programm einfach durch Abspeichern von Teilen in kleinere Einheiten aufzusplitten. So etwas geht mit solchen Programmen auch nicht.

Gut, die Bedienung des GUI Designers und das Aussehen kann sicherlich noch um einiges verbessert werden. Dass ich alles auf einmal bis in das letzte Detail gleich ganz perfekt gestalte, würde etwas lange dauern. Aber mit Sicherheit kann man sagen, so eine Konzeption hat sonst niemand. Und in dieser - ganz simplen - Konzeption steckt viel drin, was sonst nirgendwo geht.

Trennung von Code und GUI ist eine gute Idee. Aber nur solange alles noch überschaubar ist. Will man zu 24 GUI Modulen auch noch 24 Code Module machen? Und was passiert, wenn man von den 24 GUI Modulen 12 löscht und dafür 20 nachlädt, und das immer wieder macht, bis es in die hundert geht?
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: Du schreibst immer nur, wie toll Dein eigener Designer ist, gesehen hat ihn außer Dir hier aber noch niemand. Perfekt muß es am Anfang noch nicht sein, daher "release early, release often".
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Sirius3 hat geschrieben:"release early, release often".
+1


@Alfons Mittelmeyer: Ich will nicht sagen, das pygubu das non+ultra ist.
Ich frage mich nur, ob es nicht Sinnvoller ist, sich bei dem Projekt einzubringen, anstatt das Rad zum x-ten Mal neu zu erfinden ;)

Was pygubu auch fehlt ist eine schöne Möglichkeit grid layouts *bequem* zu entwerfen. Denn auch dort muß man mit Zahlen hantieren.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Alfons

Da möchte ich mich Sirius3 und jens nur anschliessen. Von dir haben wir bis jetzt ausser viel schwer verdaubar geschriebenes nichts gesehen und das ist alles. Sorry dies kann sich in Zukunft vielleicht noch ändern. Hut ab! Mit dem GUI Designer for Tkinter hat Alejandro Autalan eine super Arbeit erbracht, welche bis jetzt noch nicht ebenbürtiges in diese Richtung für Tkinter hat. Eine Arbeit wo es sich lohnt darauf aufzubauen.

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Alfons Mittelmeyer hat geschrieben:Die Frage ist nur, wie Ihr mit Eurer Art der Programmierung damit umgehen würdet.
Bei einem GUI-Designer möchte ich mir um meine Art der Programmierung gar keine Gedanken machen, wenn ich ehrlich bin. Wie der name ja schon sagt "designe" ich darin die GUI. Aus meinem Code, möchte ich die Elemente darin einfach erreichen können, wie das Toolkit das vorsieht.
Alfons Mittelmeyer hat geschrieben:Außerdem enthält der GUI Designer Möglichkeiten, ein langes Programm einfach durch Abspeichern von Teilen in kleinere Einheiten aufzusplitten. So etwas geht mit solchen Programmen auch nicht.
Neee, ist ja auch ein GUI-Designer. Warum sollte der Programme aufsplitten?
Alfons Mittelmeyer hat geschrieben:Trennung von Code und GUI ist eine gute Idee. Aber nur solange alles noch überschaubar ist. Will man zu 24 GUI Modulen auch noch 24 Code Module machen? Und was passiert, wenn man von den 24 GUI Modulen 12 löscht und dafür 20 nachlädt, und das immer wieder macht, bis es in die hundert geht?
Es ist immer eine gute Idee Geschäftslogik und Oberfläche zu trennen.
Und ich habe schon in ein paar Programmiersprachen mit GUIs gespielt. Ich habe nie "GUI-Module gelöscht" oder irgend etwas nachgeladen, das so spektakulär war, dass das hierzu zu passend scheint ;)
Antworten