Sirius3 hat geschrieben:@Alfons Mittelmeyer: weil Du hier noch nie Dein wahres Ziel gepostest hast, tu ich mal das für Dich. Widersprich mir, wenn ich falsch liege: Du willst eine GUI-Anwendung schreiben, wo Nutzer interaktiv Fenster gestalten können und mit Funktionen hinterlegen können. Diese Fenster können gespeichert, verschickt, ins Internet geladen werden, von dort wieder von anderen Nutzern heruntergeladen werden, bearbeitet oder benutzt werden. Also alles in einem, Editor und Ausführung von beliebig vielen "Apps".
Da sind zwei oder gar drei verschiedene Ziele vermischt. Das eine ist der GuiEditor zur Erstellung, Übernahme aus bestehenden Programmen, Modifizierung und Speicherung der GUI, der auch einige zusätzliche Gimmicks enthalten wird. Da hätte ich etwa Nachladelabel, die aussehen wie solche <href Label auf Webseiten. Weiss allerdings nicht, ob ich sie wieder herausnehme, weil man sie leicht selber machen kann. Das andere ist DynTkInter, eine tkinter Erweiterung, welche dynamische GUIs ermöglicht, die man zur Laufzeit jederzeit modifizieren, ganz oder teillöschen und nachladen kann. Auf DynTkInter - wie es funktioniert hatte ich im Thread spazierengehen in der GUI dargestellt - beruht auch der GuiEditor. Das dritte wären dann weitere Dynamische Applikationen, die auf DynTkInter beruhen und womit man dann eine Menge anstellen kann. Was genau das für Applikationen sein könnten, habe ich mir allerdings noch nicht überlegt. DynTkInter funktioniert auch mit Sourcen, die in TkInter geschrieben sind und es können auch Gui Teile, die in tkinter geschrieben sind, nachgeladen werden. Hierfür reicht dann allerdings nicht eine Quellangabe für ein Script, sondern es ist noch eine zweite Angabe erforderlich, nämlich welche Funktion oder Methode darin mit der Angabe des Parents aufzurufen ist.
Erstes Ziel ist, den GuiEditor zu überarbeiten, damit der Code gut aussieht, ihn fertigzustellen, indem ich mich noch mit PanedWindows und Menüs befasse und weitere Speicherroutinen einzubauen also nicht nur DynTkInter Quellcode, sondern auch tkinter Quellcode und so etwas wie qt ui Dateien oder Ähnliches.
Sirius3 hat geschrieben:Dazu ein paar Anmerkungen:
GUIs sind Event-gesteuert. Gerade wenn es viele Apps geben soll, ist es fast unumgänglich, eine App als Klasse zu definieren. Daher ist es schwierig, Interaktivität prozedural zu steuern, ein Skript das nacheinander Befehle ausführt widerspricht dem Grundaufbau einer GUI.
Es empfielt sich, umfangreiche Apps als Klasse zu definieren. Wenn jemand lieber globale Funktionen nimmt, kann ich auch damit umgehen - d.h. am Ende die globalen Referenzen beseitigen. Von Interaktivität prozedural steuern war keine Rede und ein Script das hintereinander Befehle ausführt steht in keinerlei Gegensatz zu einer GUI. Ein typisches Script für eine App sähe so aus:
Hier haben wir zwei Befehle, die hintereinander ausgeführt werden, nämlich die Definition der Klasse und deren temporäre Instanzierung
Sirius3 hat geschrieben:Um Fenster laden und speichern zu können, braucht es ein Datenformat, das am Besten Ähnlichkeiten zur internen Struktur hat, also eine Art Baum, wo Knöpfe und Eingabefelder die Blätter sind, die zusätzlich noch Attribute haben. Schau Dir mal ui-Dateien von QT an.
Das am Besten für DynTkInter geeignete Format ist DynTkInter Sourcecode. Für einfache tkinter Programme und Beispiele biete ich dann auch Speicherung in tkinter Sourcecode an und für komplexere Programm, die auch ihre eigenen Widget Klassen wollen, so etwas ähnliches wie Qt ui Files. Muss mir allerdings noch Gedanken machen, wie das genau aussehen soll. Kann man ja später darüber diskutieren.
Sirius3 hat geschrieben:Jetzt kommen wir zum Punkt Aktionen: die hängen ja nicht in der bloßen Luft. Neben der Außenansicht (GUI) gibt es auch noch das Innenleben (Geschäftslogik) die beide erstmal nichts miteinander zu tun haben. Die Geschäftslogik sollte ohne GUI entwickelt und getestet werden, erst danach, wird sozusagen als Aufsatz eine GUI gemacht. Änderungen bedeuten dann oft eine Änderung der Datenstrukturen, und damit muß man die App komplett neustarten.
Ja haargenau so sollte programmiert werden. GUI Callbacks sollen keinerlei App spezifischen Funktionen aufrufen. Nehmen wir das Beispiel einer Eingabemaske. Nach Eingabe gibt es einen Button für Daten übernehmen. Alles was dieser Button dann tun soll ist die Daten zu senden mit einer bestimmten Message ID. Und das war es dann für die GUI. Und die App richtet dann einen Callback für diese Message ID ein und ruft in diesem Callback dann ihre Funktionen oder Methoden asuf, welche die Daten weiterverarbeiten. Genauso gibt es auch den umgekehrten Weg, dass die App Daten an die GUI sendet.
Sirius3 hat geschrieben:Und damit komme ich zum letzten Punkt: viele Apps in einer Anwendung wird selten gemacht, weil die Nachteile überwiegen. Getrennte Prozesse sind voreinander geschützt. In Python kann so ziemlich alles dynamisch geändert werden. Eine fehlerhaft programmierte App kann damit das ganze Programm instabil machen. Und das will man normalerweise nicht haben.
Wie ich das mache, muss ich mir überlegen, wenn ich etwas mit vielen Apps mache. Jetzt überlege ich es mir noch nicht.
Sirius3 hat geschrieben:Selbst so große Firmen wie Microsoft haben in ihren Visual XY den (GUI-)Editor vom Ausführen der Programme getrennt. Vielleicht gibt es den ein oder anderen Programmieranfänger, der Deine Visionen toll findet, aber damit das Projekt erfolgreich werden kann, mußt Du Dich an erprobte Praktiken halten. Dazu zählen Module, Klassen und Methoden, keine globalen Variablen, insbesondere kein eval, das globale Zustände ändert.
Sorry, mit dem GUI Editor erstellt man GUI und führt keine Programme aus. Es ist nur ein Schmankerl, wenn man anbieten kann, dass der GUI Editor auch zu laufenden Programmen dazugeladen werden kann und deren Gui bearbeitet und abgespeichert werden kann. Ebenso ein Schmankerl, wenn man bei laufendem Programm unter bestimmten Voraussetzungen Code modifizieren und testen kann. Notwendig ist es eigentlich nicht und eigentlich habe ich es selber auch kaum verwendet. Denn ein Editor mit Syntax Highlighting gefällt mit besser als eine Eingabe in ein Text-Widget. Wenn Microsoft solche Dinge nicht anbietet, dann liegt es daran, dass das mit .Net und C/C++ nicht so einfach ist, wie mit tkinter und Python, denn so etwas geht nicht in C/C++: eval(compile("Button()"))
Naja ließe sich auch mit einer if Abfrage über alle Wiget Typen machen. Sollte man allerdings noch eigene Widget Klassen dabei berücksichtigen, wäre es mit if Abfragen gar nicht mehr machbar. Zur Zeit behandle ich nur normale tkinter Widgets und keine vom Benutzer definierten. Derjenige, der den GuiEditor für seine Apps verwendet, kann Module Klassen und Methoden nehmen wie er will. Ich benütze das DynTkInter Modul und ob ich lieber eine Klasse nehme und dann das in __init__ reinschreibe, was ich ohne Klasse gemacht hatte oder ob es übersichtlicher ist, das nicht zu tun, werde ich mir noch überlegen. Jedenfalls benutze ich dann zum Aufbau des GuiEditor einen gesonderten Namensraum, damit es mit Sicherheit keinerlei Überschneidungen mit einer App gibt und globale Funktionen für diesen gesonderten Namensraum sind auch kein Problem, weil sie automatisch - naja, durch die Ladefunktion - wieder beseitigt werden. Und kein eval? Eval läßt sich nicht vermeiden, da jedenfalls ein import sich verbietet - könnte man ja auch nur einmal laden - scripts muss man so oft laden können, wie man will. Ja und wenn ohne import, wie dann? Oder ist exec akzeptabel?
Sirius3 hat geschrieben:Das was Du bisher gezeigt hast, ist kein Python, sondern eine Art maschinennahes BASIC in Python-Syntax. Der Vorteil von Python ist, dass man sich um vieles keine Gedanken machen muß, wenn man sich an ein paar einfache Regeln hält. Bei Deiner neuen Programmiersprache muß sich der Programmierer dagegen viele Gedanken um Dinge machen, wo die meisten Programmierer froh sind, sie seit etlichen Jahren los zu sein.
Das ist keine neue Programmiersprache. Das ist entstanden, weil ich da noch nicht wußte, wie ich Definitionen wieder wegbekomme. Gar keine Variablen verwenden ausser einem Stack und einem Dictionary und keine Funktionen zu verwenden außer compilertem Code, geht auch. Aber sieht eben abscheulich aus. Jetzt weiß ich ja durch unsere Diskussion, wie ich auch unter Verwendung von Funktionen und Ähnlichem, wieder alles wegbekomme - del nehme ich hierbei nicht - und kann dann den GuiEditor so umschreiben, dass der Code dann gut aussieht.