Gui Designer auf GitHub

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

Hatte mit dem Gui Designer nicht weiter gemacht. Dafür ist er hier zum Anschauen auf GitHub: https://github.com/AlfonsMittelmeyer/py ... -messaging
Interessant sicherlich auch, wenn man hier fast alle Config und Layout Optionen im Überblick hat.
Beschreibung habe ich aber noch keine.

Start mit python3 main.py
BlackJack

@Alfons Mittelmeyer: Git/Github ist für Quelltext und nicht um da *ein* ZIP-Archiv mit dem Quelltex drin einzustellen. Du benutzt das falsch.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@BlackJack Stimmt. War froh, dass ich überhaupt etwas draufgebracht habe. Muss mich mit Github noch etwas näher befasssen
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Hier eine Einführung in git
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@sparrow Danke. Auf meinem PC mußte ich git erst installlieren. Und dafür gab es dann ein fertiges Binary für Ubuntu. Da war meine Sorge, wie bekommme ich das auf meinen MK808B in der Größe einer halben Zigarettenschachtel drauf. Brauche ich da den Source Code? Aber glücklicher Weise hatte der das schon drauf.

Einiges verstehe ich von git allerdings noch nicht. In welchem Forum soll man da fragen? Denn tkinter spezifisch ist das ja nicht.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Alfons

Endlich eine Zusammenfassung der vielen Skripte betreffs deines GuiDesigner's. Habe den Überblick schon längst verloren. Nun interessiert mich dein Projekt wieder. Habe das .zip-Archiv von Github heruntergeladen und entpackt. Ich starte den GuiDesigner mit:
python3.4 main.py
Als erstes sucht er nach dem proxy-Modul, welches auf meine Maschine noch nicht installiert ist. Konnte nur das zope.proxy 4.1.6 Packet finden (Ist dieses Packet das richtige?). Die Datei proxy.py musste ich noch mit 2to3 -w proxy.py für den Einsatz unter Python3.4 umwandeln. Ein neuer Startversuch mit python3.4 main.py wirft folgende Exception:
line 598, in __init__
proxy = dynproxy.Proxy(self)
AttributeError: 'module' object has no attribute 'Proxy'
Das zope.proxy 4.1.6 Packet besitzt diese Attribut Proxy nicht.

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

@wuf Sorry, da hatte noch ein Modul gefehlt. Jetzt ist es aber richtig drauf.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

BlackJack hat geschrieben:@Alfons Mittelmeyer: Git/Github ist für Quelltext und nicht um da *ein* ZIP-Archiv mit dem Quelltex drin einzustellen. Du benutzt das falsch.
Jetzt habe ich es richtig drauf.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Alfons

Danke! Jetzt hat es geklappt. Machte schon meine ersten Gehversuche mit deinem DynTkinter GuiDesigner. Chapeau dein Projekt funktioniert , da es sich erst im Anfangsstadium befindet schon recht gut. Die Handhabung ist einfach und der grafische Aufbau macht schon einen guten Eindruck. Ich wünsche dir auf alle Fälle viel Erfolg bei der Weiterentwicklung deines interessanten Projektes. Ich werde dein Projekt sicher weiter verfolgen und unterstützen soweit es mir möglich ist.

N.B. Nehme an der FileDialog für save, load & run und load & edit kommt noch. Ein save as wäre auch noch gut.

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

@wuf Ja an einen Filedialog sollte ich auch denken.
Übrigens bei save auf die Root gehen (Button '\\'). Sonst speicherst Du nur ab da, wo Du im Verzeichnisbaum bist. Allerdings, wenn Du dann auch noch von der Root aus speicherst, dann geht das auch. Nur hast Du dann eben zwei Scripts. Damit habe ich dann den GUI Designer in 24 Module zerteilt. Andere Save Routinen in anderen Formaten muss ich auch machen, damit es nicht nur mit DynTkInter geht.

Zuerst sollte ich mich aber erst einmal um die Besonderheiten für PanedWindow und Menü kümmern.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@wuf Hab noch in GuiDesigner/guidesigner/PlaceLayout.py das Widget Bewegen verbessert mit after statt <B1-Motion>. Das waren zuvor unschöne Sprünge. Verbesserung nicht im zip file nachgezogen.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: bevor Du noch weiter tausende Zeilen Code produzierst, solltest Du ihn dringend aufräumen. Deine Namensgebung ist inkonsistent. Am besten hältst Du Dich an die Vorgaben, die in PEP8 stehen. Eingerückt wird immer mit 4 Leerzeichen pro Ebene. Nach einem mit Doppelpunkt abgeschlossenen Befehl beginnt eine neue Zeile. global solltest Du nicht verwenden, ich habe auch keins gefunden, das einen Effekt hätte. Ein "except: pass" macht Dir Fehlersuche unmöglich.

Alle Dateien im GuiDesigner/guidesigner-Verzeichnis sind irgendwie kaputt. Jedenfalls ist die Endung .py irreführend, weil das keine Python-Dateien sind. Namen sollten immer explizit importiert werden und nicht aus dem nichts auftauchen. Verschachtelte Funktionen machen nur selten Sinn. Statt "widget('xy')" zu schreiben, kann man auch gleich lokale Variablen/Klassenattribute nehmen.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@BlackJack Dass es noch einiges aufzuräumen gibt, ist klar. Das betrifft hauptsächlich das Modul DynTkInter.py. Den Prfoxy habe ich da schon rausgenommen. Der soll aber dann mal EventBroker heissen. Die Speicherroutine muß umgeschrieben werden und es soll verschiedene Versionen geben. Die Widgets sollte ich rausnehmen usw.

Aber die Dateien im GUI Designer Verzeichnis sind alle OK. Gut da kann man auch noch etwas verschönern. Da kommt noch Code vor, bei dem ich alle Funktionen function genannt habe. Aber dann bin ich darauf gekommen, dass man drum herum auch eine Funktion main machen kann, damit dann die anderen Funktionenen nicht mehr global sind. Das wäre noch so ein Code:

Code: Alles auswählen

def main(parent):

	Button('Layout',text="""ON""",bg='green').grid(column='3',sticky='ew',row='0')
	Button('Create',text="""ON""",bg='green').grid(column='1',sticky='ew',row='1')
	Button('Config',text="""ON""",bg='green').grid(column='1',sticky='ew',row='0')
	Label('Label',text="""Config:""",width='6').grid(row='0')
	Label('Label',text="""Layout:""").grid(column='2',row='0')
	Label('Label',text="""Create:""",width='6').grid(row='1')

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

	# The command is initialized with config options switched off (False)
	# When pressed, this switch is toggled and a message 'SHOW_CONFIG' is sent, which contains this ON/OFF value
	# Further the button text is toggled between ON and OFF and the bg color between green and orange

	widget("Config").mydata = False
	widget("Layout").mydata = False
	widget("Create").mydata = True

	def function(me):
		me.mydata = not me.mydata
		send("SHOW_CONFIG",me.mydata)
		if me.mydata: me.config(text="OFF",bg="orange")
		else: me.config(text="ON",bg="green")

	widget("Config").do_command(function,wishWidget=True)

	# This button is nearly the same, but sends a 'SHOW_LAYOUT' message

	def function(me):
		me.mydata = not me.mydata
		send("SHOW_LAYOUT",me.mydata)
		if me.mydata: me.config(text="OFF",bg="orange")
		else: me.config(text="ON",bg="green")

	widget("Layout").do_command(function,wishWidget=True)

	# This button is nearly the same, but sends a 'HIDE_CREATE' message

	def function(me):
		me.mydata = not me.mydata
		send("HIDE_CREATE",me.mydata)
		if not me.mydata: me.config(text="OFF",bg="orange")
		else: me.config(text="ON",bg="green")

	widget("Create").do_command(function,wishWidget=True)

	send("HIDE_CREATE",True)

### ========================================================
Und für die Tabs muss icvh mir ein Programm schreiben, das die Tabs durch vier Leerzeichen ersetzt. Statt viermal Tab drücken 16 Leerzeichen eintippen, macht nämlich keinen Spass. Und dann hat man doch hin und wieder einen Tab gedrückt mit vielen vielen Febhlermeldungen. Also das mit dem Abzählen von Leerzeichen ist unschön. Muss ich eben noch ein Programm zum Tab Rausmachen schreiben.

Ja bei der Endung .py denkt man an Module, obwohl es lediglich Scripts sind. Da hatte ich mir auch schon eine andere Dateiendung überlegt, aber dann kein Syntax Highlighting gehabt und deshalb dann doch .py gelassen.

Das mit den Namen, da habe ich noch einen Sternchenimport drin. Könnte für den Designer vorerst noch egal sein, kann man mal beseitigen, eventuell auch mit einem Programm. Da muss ich mir aber erst eine Funktionsdatenbank anlegen, damit das geht.

Und verschachtelte Funktionen habe ich nicht, wenn man einmal davon absieht, dass noch ein main herum ist. Eine Main-Klasse zu machen und das dann in die init zu schreiben, sehe ich auch nicht besonders sinnvoll an.

Und widget('xy') muss ich schreiben. Lokale Variablen machen da keinen Sinn, da das mit den Widgets ja sowieso mal XML werden soll, wenn ich mir das Abspeicherformat überlegt habe. Und mit lokalen Variablen könnte der Code zur Laufzeit auch gar nicht mehr modifiziert werden, da es dann die lokalen Variablen gar nicht mehr gibt.

Wäre der Code so jetzt besser:

Code: Alles auswählen

def main(parent):

    Button('Layout',text="""ON""",bg='green').grid(column='3',sticky='ew',row='0')
    Button('Create',text="""ON""",bg='green').grid(column='1',sticky='ew',row='1')
    Button('Config',text="""ON""",bg='green').grid(column='1',sticky='ew',row='0')
    Label('Label',text="""Config:""",width='6').grid(row='0')
    Label('Label',text="""Layout:""").grid(column='2',row='0')
    Label('Label',text="""Create:""",width='6').grid(row='1')

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

    # The command is initialized with config options switched off (False)
    # When pressed, this switch is toggled and a message 'SHOW_CONFIG' is sent, which contains this ON/OFF value
    # Further the button text is toggled between ON and OFF and the bg color between green and orange

    widget("Config").mydata = False
    widget("Layout").mydata = False
    widget("Create").mydata = True

    def callback(me,message_to_send):
        me.mydata = not me.mydata
        send(message_to_send,me.mydata)
        if me.mydata: me.config(text="OFF",bg="orange")
        else: me.config(text="ON",bg="green")

    def call(widget_name,message_to_send):
        widget(widget_name).do_command(callback,message_to_send,True)

    call("Config","SHOW_CONFIG")
    call("Layout","SHOW_LAYOUT")
    call("Create","HIDE_CREATE")

    send("HIDE_CREATE",True)

### ========================================================
Ich meine, was will man da gross mit Klassen? Es handelt sich lediglich um tkintger Widgets und um zu kreieren, braucht man keine extra Klasse und an die pappt man dann eine Callback Funktion dran. Und dafür braucht man auch keine Klasse. Also Widgets mit drangepappten Callbacks, so ist der GUI Designer aufgebaut.

Ach, ist mir noch eingafallen, das ist ja ga kein Sternchenimport. Das läuft einfach nur im Namespace von DynTkInter.py
Zuletzt geändert von Alfons Mittelmeyer am Mittwoch 23. September 2015, 22:36, insgesamt 2-mal geändert.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Jeder Editor, der den Namen verdient, kann beim Drücken der Tab-Taste 4 Leerzeichen einfügen. Bei Python-Files sollte das der Default sein. Die main-"Funktionen" machen so keinen Sinn. Niemand sollte dazu gezwungen werden, eine krude Skript-Sprache zu lernen, die auch noch fast so aussieht wie Python, mahc daraus ganz normale Python-Module, damit verlierst Du nichts, und das vereinfacht Dein ganzes Programm.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:Jeder Editor, der den Namen verdient, kann beim Drücken der Tab-Taste 4 Leerzeichen einfügen. Bei Python-Files sollte das der Default sein. Die main-"Funktionen" machen so keinen Sinn. Niemand sollte dazu gezwungen werden, eine krude Skript-Sprache zu lernen, die auch noch fast so aussieht wie Python, mahc daraus ganz normale Python-Module, damit verlierst Du nichts, und das vereinfacht Dein ganzes Programm.
Also ich benutze gedit. Das ist Standard für Linux. Da kann ich zwar die Einrückung von 4 Leerzeichen einstellen. Aber er macht dann einen Tab und stellt diesen mit dem Abstand von vier Leeteichen am Bildschirm dar.

Und das ist keine krude Scriptsprache, sondern Python. Nur ist es kein tkinter, sondern DynTkInter und das wird dann durch XML ersetzt.
BlackJack

@Alfons Mittelmeyer: Nur wenn das Kreuzchen bei der Option das Leerzeichen statt Tabulator-Zeichen eingefügt werden sollen nicht gesetzt ist.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@BlackJack Danke, jetzt habe ich gesehen, dass es da auch "Indent Type" gibt und nicht nur "Indent Width".
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Sirius3 In einer früheren Diskussion wurde geschrieben, dass das DynTkInter Format niemand haben will. Von JSON war die Rede und von XML. Wie stellt man sich das dann vor?

Code: Alles auswählen

# statt DynTkInter:
Button('Layout',text="""ON""",bg='green').grid(column='3',sticky='ew',row='0')

#evtl. JSON so oder doch lieber XML?
{"Layout": {"layout": {"type": "grid", "parameters": {"column": "3", "sticky": "ew", "row": "0"}}, "tkclass": "Button", "config": {"text": "ON", "bg": "green"}}}
Als Zwischenschritt könnte ich ja schon mal die Save Routine ändern und vereinfachen, denn das geht ja auch:

Code: Alles auswählen

Button('Layout',{"text": "ON", "bg": "green"}).grid({"column": "3", "sticky": "ew", "row": "0"})
Und statt die Syntax selber zu machen, brauche ich da nur JSON zu nehmen.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:Ein "except: pass" macht Dir Fehlersuche unmöglich.
Da hast Du ja tolle Regeln im Kopf. Wenn der Benutzer als Farbe "grün" statt "green" eingibt, soll ich dann wirklich mywidget['bg']='grün' ohne except machen? Ja, wenn das System dann abstürzt, dann merkt er, daß er das falsch eingegeben hat. Aber freuen wird es ihn sicherlich nicht, wenn dann vielleicht eine Stunde Arbeit umsonst war.

Und unmöglich ist da die Fehlersuche nicht. Wenn man nämlich nach kurzer Animation das Eingabefeld wieder mit mywidget['bg'] füllt, merkt der Benutzer auch, dass das System das nicht angenommen hat. Außerdem sieht er auch, dass das Widget nicht grün geworden ist.
Programmabsturz als Empfehlung? Nein Danke.

Wahrscheinlich hast Du aber gemeint, man soll eine Fehlerbehandlung einbauen, wie etwa mit print den Fehler ausgeben.
Aber unmöglich ist es nicht, den Fehler zu erkennen, denn Gegenlesen geht auch.
BlackJack

@Alfons Mittelmeyer: Wenn eine Ausnahme eintritt und man die behandelt dann sollte man sie auch wirklich behandeln und nicht einfach nur ignorieren. Ausserdem ging es um die Fehlersuche in Deinem Programm, also Fehler die Du vielleicht gemacht hast und nicht um Fehleingaben vom Benutzer. Du hast zum Beispiel mindestens einen `NameError` in dem Code weil Du den Namen eines Arguments innerhalb einer Methode anders geschrieben hast als in der ``def``-Zeile. Wenn Du diese Methode innerhalb eines solchen ``try``/``except``-Blocks verwendest, dann wird die Fehlersuche schwieriger als sie sein müsste.
Antworten