tkinter GUI Designer

Fragen zu Tkinter.
Benutzeravatar
sparrow
User
Beiträge: 4587
Registriert: Freitag 17. April 2009, 10:28

Alfons Mittelmeyer hat geschrieben:Mein GUI Designer generiert zuerst einmal überhaupt keine Daten. Wenn Du auf grid drückst, dann wird der grid ausgeführt. Lediglich merkt sich der GUI Designer Referenzen auf die verwendeten Widgets. Und aus diesen Referenzen kann dann der Code generiert werden. xml könnte ich natürlich auch generieren. Aber wozu zuerst xml und aus xml dann wieder Python generieren, wie es pygubu tut, wenn man gleich python mit tkinter generieren kann?
:shock:
Liest du die Beiträge in deinen Threads auch? Es wurde doch bereits geschrieben, wie das zum Beispiel im Qt-Designer läuft (Stichword .ui). Wozu zuerst XML und dann Python? Ganz einfach: XML-ist recht simpel und ein verbreitetes Format.
Die Frage, die du dir eigentlich stellen musst: Warum Python, und das Programm dadurch unnötig einschränken, wenn ich XML haben könnte, wofür es für so ziemlich jede Sprache etwas gibt um das schmerzfrei zu lesen. Wenn du Python-Code generierst, schränkst du die Zielgruppe erheblich ein, denn Tk wird ja nicht nur mit Python verwendet.
Alfons Mittelmeyer hat geschrieben:Also, bitte Vorstellungen zur Bedienung formulieren, wenn Ihr so etwas wünscht.
Ich würde sagen: zeig erst einmal das Programm, dann können wir uns über Vorstellungen bei der Bedienung unterhalten. Und damit meine ich keine Screenshots.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

sparrow hat geschrieben:Ich würde sagen: zeig erst einmal das Programm, dann können wir uns über Vorstellungen bei der Bedienung unterhalten. Und damit meine ich keine Screenshots.
Sorry, wie soll ich ein Programm zeigen, das noch nicht existiert? Das war ein manuelles Gridlayout mit dem GUI Designer. Aber wenn Du das unbedingt sehen willst:

Code: Alles auswählen

Frame(bg='#a0a0a0',height='30',width='2').grid(row='1')
Frame(bg='#a0a0a0',height='2',width='60').grid(column='1',row='0')
Frame(bg='#a0a0a0',height='30',width='2').grid(column='2',row='1')
Frame(bg='#a0a0a0',height='2',width='60').grid(column='3',row='0')
Frame(bg='#a0a0a0',height='30',width='2').grid(column='4',row='1')
Frame(bg='#a0a0a0',height='2',width='60').grid(column='5',row='0')
Frame(bg='#a0a0a0',height='30',width='2').grid(column='6',row='1')
Frame(bg='#a0a0a0',height='2',width='60').grid(column='1',row='2')
Frame(bg='#a0a0a0',height='2',width='60').grid(column='3',row='2')
Frame(bg='#a0a0a0',height='2',width='60').grid(column='5',row='2')
Frame(bg='#a0a0a0',height='30',width='2').grid(row='3')
Frame(bg='#a0a0a0',height='30',width='2').grid(column='2',row='3')
Frame(bg='#a0a0a0',height='30',width='2').grid(column='4',row='3')
Frame(bg='#a0a0a0',height='30',width='2').grid(column='6',row='3')
Frame(bg='#a0a0a0',height='2',width='60').grid(column='1',row='4')
Frame(bg='#a0a0a0',height='2',width='60').grid(column='3',row='4')
Frame(bg='#a0a0a0',height='2',width='60').grid(column='5',row='4')
Benutzeravatar
sparrow
User
Beiträge: 4587
Registriert: Freitag 17. April 2009, 10:28

Alfons Mittelmeyer hat geschrieben:Sorry, wie soll ich ein Programm zeigen, das noch nicht existiert?
Du redest hier recht viel davon was ein Programm macht (anderen Programmen fehlt "Essentielles"), aber es existiert noch gar nicht?
Dann würde ich sagen: Butter bei die Fische, und wenn dann mal was da ist, dann Kommentare zur Bedienung und Nutzbarkeit einholen.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

sparrow hat geschrieben:
Alfons Mittelmeyer hat geschrieben:Sorry, wie soll ich ein Programm zeigen, das noch nicht existiert?
Du redest hier recht viel davon was ein Programm macht (anderen Programmen fehlt "Essentielles"), aber es existiert noch gar nicht?
Dann würde ich sagen: Butter bei die Fische, und wenn dann mal was da ist, dann Kommentare zur Bedienung und Nutzbarkeit einholen.
Das Programm existiert, denn ich habe es. Es ist nur noch nicht veröffentlicht. Und bevor ich es veröffentliche, hätte ich gerne Informationen, was Ihr braucht und noch wünscht. Und der Wunsch war ein *schönes* Grid Layout.
BlackJack

@Alfons Mittelmeyer: Wir brauchen und wünschen das Programm zu sehen, sonst macht das Diskutieren über Details von einem Programm das keiner ausser Dir kennt, wenig Sinn.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

BlackJack hat geschrieben:@Alfons Mittelmeyer: Wir brauchen und wünschen das Programm zu sehen, sonst macht das Diskutieren über Details von einem Programm das keiner ausser Dir kennt, wenig Sinn.
OK, ist auch eine Idee. Dann ziehe ich mich für eine Zeit von der Diskussion zurück. Mache das Programm fertig - *schönes* GridLayout, die hier besprochenenen Interface Funktionen (auch zur Verwendung eigener Klassen), Generierung von tkinter Code und nicht nur DynTkInter Code (xml mache ich jetzt noch nicht), Ersetzung von Entries mit Zahlen durch Spinboxen, und noch schauen, was ich für PanedWindows und Menüs machen muss.

Wenn Ihr mir keine Vorstellungen für das GridLayout nennen wollt, muss ich mir eben selber den Kopf zerbrechen, wie Ihr das vielleicht wünschen würdet.
Benutzeravatar
snafu
User
Beiträge: 6902
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wann kommst du wieder? An Heiligabend? :D
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

snafu hat geschrieben:Wann kommst du wieder? An Heiligabend? :D
Wahrscheinlich, wenn ich die Bedienung des GridLayouts vorstelle. Für letzte Anmerkungen, bevor ich es veröffentliche.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

sparrow hat geschrieben:Ich habe nie "GUI-Module gelöscht" oder irgend etwas nachgeladen, das so spektakulär war, dass das hierzu zu passend scheint ;)
Gelöscht habe ich bisher auch keine. Bei großen Anwendungen oder wechselnden Teilanwendungen kann man es brauchen. Aber Nachladen möchte ich schon. Ihr benutzt ja auch import. Bei mir ist es eine Ladefunktion, die öfter als einmal aufrufbar ist und die nicht in ein Modul importiert. Das wäre etwa das Script, welches die fünf Teile des GUI Creators lädt:

Code: Alles auswählen

def main(parent):

	### NAME CreateFrame	
	CreateFrame = Frame(parent)
	gui.load_Script(CreateFrame,"guidesigner/CreateFrame.py")
	CreateFrame.grid(sticky='n',row='0')

	### NAME CreateAndLayout
	CreateAndLayout = Frame(parent)
	gui.load_Script(CreateAndLayout,"guidesigner/CreateAndLayout.py",)
	CreateAndLayout.grid(column='1',sticky='n',row='0')
	
	### NAME ConfigOptions
	ConfigOptions = LabelFrame(parent)
	gui.load_Script(ConfigOptions,"guidesigner/ConfigOptions.py")
	ConfigOptions.grid(row='0', column='2',sticky='n')

	### NAME DetailedLayout
	DetailedLayout = Frame(parent)
	gui.load_Script(DetailedLayout,"guidesigner/DetailedLayout.py")
	DetailedLayout.grid(row='0',column='3',sticky='n')

	### NAME Selection
	Selection = LabelFrame(parent)
	gui.load_Script(Selection,"guidesigner/Selection.py")
	Selection.grid(row = '0',column = '4', sticky='n')

	### CODE ===================================================

	ConfigOptions.grid_remove()
	DetailedLayout.grid_remove()

	### ========================================================
Diese Ladefunktion lädt das jeweilige Script und ruft darin die Funktion main mit parent Übergabe auf. Und auf diese Art und Weise lade ich insgesamt 24 Scripte
Benutzeravatar
snafu
User
Beiträge: 6902
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Und `load_Script()` importiert die angegebene Datei und übergibt ihr über eine spezielle Schnittstelle das zuvor erstellte Exemplar des GUI-Widgets, oder wie muss ich mir das vorstellen?

EDIT: Achso, das ist wohl mit der "parent-Übergabe" an `main()` gemeint, richtig?
Zuletzt geändert von snafu am Freitag 28. August 2015, 14:17, insgesamt 1-mal geändert.
Sirius3
User
Beiträge: 18328
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: es handelt sich also nicht um Skripte sondern um Module. Und was ist jetzt daran von Vorteil im Gegensatz zu einem viel einfacheren Import?
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:@Alfons Mittelmeyer: es handelt sich also nicht um Skripte sondern um Module. Und was ist jetzt daran von Vorteil im Gegensatz zu einem viel einfacheren Import?
Es geht darum, dass ich eine Funktion 'main' in einem Script aufrufen will. Es handelt sich nicht um eine Library. Es sehe keinen Sinn darin, eine Funktion zu importieren, damit ich sie dann einmalig aufrufe. Warum sollte ich so etwas im Modulspeicher ablegen?

Vielleicht sollte ich lieber doch das xml Format vorziehen. Dann motzt wenigstens keiner mehr, wenn ich eine xml Datei nicht als Modul importiere.

Man könnte ja auch eine xml Datei laden und dann solchen Code daraus generieren, wie es etwa pyguntu macht. Oder erwartet man dann auch, dass man einen solch genenerierten Code anschließend noch importiert?
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:Hast du schon mit den Entwicklern von pygubu gesprochen?!?

Fork + Pull request
Sorry, da gibt es nichts zu besprechen. pygubu ist ein anderes Konzept. Es handelt sich hier um einen getrennten GUI Designer, der wahrscheinlich nicht mal tkinter verwendet. Daraus werden Daten im xml Format generiert. Und daraus dann unter Python eine Python GUI erzeugt. Mein GUI Designer generiert zuerst einmal überhaupt keine Daten. Wenn Du auf grid drückst, dann wird der grid ausgeführt. Lediglich merkt sich der GUI Designer Referenzen auf die verwendeten Widgets. Und aus diesen Referenzen kann dann der Code generiert werden. xml könnte ich natürlich auch generieren. Aber wozu zuerst xml und aus xml dann wieder Python generieren, wie es pygubu tut, wenn man gleich python mit tkinter generieren kann?
Ähm. Letztlich läuft es doch auf das selbe hinaus. Man klickt sich eine GUI zusammen und will das dann irgendwie speichern und irgendwie in seinen eigentlichen Programm nutzten.

Alfons Mittelmeyer hat geschrieben: So könnte dann die Vorlage für 2 Zeilen 3 Spalten ausssehen:
Bild
Das ist ein Grid Layout mit zusätzlich eingefügten Zeilen und Spalten mit Separatorframes. Der Platz dazwischen ist leer. Darin können dann die Widgets eingefügt werden.

Jetzt muss man sich Gedanken über die Bedienung machen. Was wäre mit Maus Doppelklick, um ein Widget, das noch kein Layout hat, darin zu positionieren?
Einfach per Drag&Drop ein Widget rein packen.

Wie gesagt, schau dir existierende Lösungen an, zum bearbeiten von Tabellen. Ist kompliziert, sollte aber alles per Maus-Klicks gehen. Zellen verbinden, Inhalte einfügen/löschen/verschieben, Zeilen/Spalten einfügen/löschen usw.


Und ja, pack deinen Code einfach auf Github und gut.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
snafu
User
Beiträge: 6902
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Alfons Mittelmeyer hat geschrieben:Es geht darum, dass ich eine Funktion 'main' in einem Script aufrufen will. Es handelt sich nicht um eine Library. Es sehe keinen Sinn darin, eine Funktion zu importieren, damit ich sie dann einmalig aufrufe. Warum sollte ich so etwas im Modulspeicher ablegen?
Weil so eine `main()`-Funktion selbst von einem C64 im Speicher gehalten werden könnte und sie im Vergleich zum Speicherverbrauch des restlichen Programms (gerade inklusive GUI) sich in etwa so verhält wie das Größenverhältnis einer Schnecke zum Komposthaufen, in dem sie gerade herumkraucht. Mit anderen Worten: Es ist völlig unsinnig, sich darüber Gedanken zu machen. Und es ist daher ein völlig ungerechtfertigter Mehraufwand, hier ein eigenes Verfahren entgegen der üblichen Vorgehensweise (d.h. ``import``) einzuführen.

Oder kannst du mit Messungen basierend auf einem realitätsnahen Szenario nachweisen, dass dein Programm bei intensiver Nutzung tatsächlich durch das Ausführen von bis zu 24 `main()`-Funktionen (war doch so?) ernsthaft in Bedrängnis kommt? Ich wage, dies zu beweifeln. Und selbst wenn du 124 solcher Funktionen hättest, gäbe es kein Problem. Du hast dich da wirklich auf etwas festgefahren, was nur in deinem Kopf existiert, aber mit der Realität nichts zu tun hat. Und hierdurch legst du dir völlig unnötigerweise selbst Steine in den Weg.

Und ja: ich verwende soviele Superlative, weil ich mir bei einigen deiner Gedankengänge einfach nur an den Kopf fassen kann...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Diskussionen über Speicherverbrauch sind hier verboten :!: :P

eval() und Co. ebenfalls! So! :wink:


btw. ich würde kein XML machen, sondern JSON o.ä. Halt ein Format was man wirklich per Hand editieren kann.

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:Wie gesagt, schau dir existierende Lösungen an, zum bearbeiten von Tabellen. Ist kompliziert, sollte aber alles per Maus-Klicks gehen. Zellen verbinden, Inhalte einfügen/löschen/verschieben, Zeilen/Spalten einfügen/löschen usw.

Und ja, pack deinen Code einfach auf Github und gut.
Ja gute Idee. Dazu müßte man die Widgets, die noch kein Layout haben, außerhalb dieser Tabelle anordnen, damit man sie reinziehen kann, also in noch einem zweiten Grid Layout, aber im selben Container. Und beim Ziehen mit der Maus wechselt man dann auf Place Layout über. Beim Absetzen dann wieder der Wechsel zum Grid Layout. Da muss ich noch einiges nachdenken. Vielleicht überlege ich mir zu Beginn auch etwas Einfacheres, nämlich das noch nicht in der Anwendung sichtbare Widget, einfach durch Mausdoppelklick hier hineinklicken. Vom GUI Designer in die Anwendung ziehen geht nicht und die Widgets vor oder nach der Tabelle automatisch ins Gridraster zu klatschen, weiß ich nicht, ob das besonders gut ist. Normalerweise hat man die Wahl der freien Entscheidung zwischen Grid und Place. Und ich denke, dass zum ersten Platzieren in der Tabelle der Mausdoppelklick nicht schlecht wäre. Wenn das Widget mal in der Tabelle ist, ja dann ist es eventuell wieder etwas anderes, und man könnte eventuell mehr tun, wie etwa mehrere Widgets markieren und als Gruppe verschieben. Naja, vielleicht später.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

HI Alfons

Ich habe dein Skript von:
http://www.python-forum.de/viewtopic.ph ... 28#p282428

noch ergänzt da es für mich schwierig ist nur geschriebenes im Kopf ablaufen zu lassen:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

try:
    # Tkinter for Python 2.xx
    import Tkinter as tk
except:
    # Tkinter for Python 3.xx
    import tkinter as tk
    
    
def main(parent):
 
        ### NAME CreateFrame   
        CreateFrame = tk.Frame(parent)
        gui.load_Script(CreateFrame,"guidesigner/CreateFrame.py")
        CreateFrame.grid(sticky='n',row='0')
 
        ### NAME CreateAndLayout
        CreateAndLayout = tk.Frame(parent)
        gui.load_Script(CreateAndLayout,"guidesigner/CreateAndLayout.py",)
        CreateAndLayout.grid(column='1',sticky='n',row='0')
       
        ### NAME ConfigOptions
        ConfigOptions = tk.LabelFrame(parent)
        gui.load_Script(ConfigOptions,"guidesigner/ConfigOptions.py")
        ConfigOptions.grid(row='0', column='2',sticky='n')
 
        ### NAME DetailedLayout
        DetailedLayout = tk.Frame(parent)
        gui.load_Script(DetailedLayout,"guidesigner/DetailedLayout.py")
        DetailedLayout.grid(row='0',column='3',sticky='n')
 
        ### NAME Selection
        Selection = tk.LabelFrame(parent)
        gui.load_Script(Selection,"guidesigner/Selection.py")
        Selection.grid(row = '0',column = '4', sticky='n')
 
        ### CODE ===================================================
 
        ConfigOptions.grid_remove()
        DetailedLayout.grid_remove()
 
        ### ========================================================

def idiom_main():
    app_win = tk.Tk()
    app_win.title("AM Gui-Designer")
    
    main(app_win)
    
    app_win.mainloop()
 
 
if __name__ == '__main__':
    idiom_main()      
Diese Ergänzung öffnet mindesten ein Fensterchen was eigentlich jedes Tk-Skript tut. Dein skript wirft nun folgenden Fehler:
NameError: global name 'gui' is not defined

Konnte das Modul, welches 'gui' enthält in diesem Thread nich finden um es zu importieren. Könntest die es hier bitte hinzufügen. Danke.

Gruss wuf :wink:
Take it easy Mates!
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

wuf hat geschrieben:HI Alfons

Ich habe dein Skript von:
http://www.python-forum.de/viewtopic.ph ... 28#p282428

noch ergänzt da es für mich schwierig ist nur geschriebenes im Kopf ablaufen zu lassen:

Diese Ergänzung öffnet mindesten ein Fensterchen was eigentlich jedes Tk-Skript tut. Dein skript wirft nun folgenden Fehler:
NameError: global name 'gui' is not defined

Konnte das Modul, welches 'gui' enthält in diesem Thread nich finden um es zu importieren. Könntest die es hier bitte hinzufügen. Danke.

Gruss wuf :wink:
Das Modul kann ich hier nicht hinzufügen, denn etwa 2000 Zeilen wären etwas zuviel. Aber die Funktion kann ich Dir geben:

Code: Alles auswählen

def load_Script(parent,filename):
    try: handle = open(filename,'r')
    except: 
        print("Couldn't open file: " + filename)
        return
    code = handle.read()
    handle.close()
    evcode = compile(code,filename,'exec')
    exec(evcode)
    locals()['main'](parent)
spaghetticode

[OT]Bekommt außer mir eigentlich niemand Kopfschmerzen?[/OT]
Benutzeravatar
snafu
User
Beiträge: 6902
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

spaghetticode hat geschrieben:[OT]Bekommt außer mir eigentlich niemand Kopfschmerzen?[/OT]
Falls du wegen seinem Code meinst: Mehr als genug. Das wurde hier schon über einige Threads verteilt auf zum Teil in den zweistelligen Bereich gehenden Seiten diskutiert, aber brachte relativ wenig. Irgendwann lässt man es dann auch mal gut sein.
Antworten