GUI Designer mit Source File update?
@Alfons Mittelmeyer: das mit dem goIn und goOut ist doch nur ein traversieren des Baums. Würde das nicht auf globalen Zuständen operieren, wäre ist viel leichter zu verstehen. Dass Dein DynTk-Designer nichts liest, ist ein Trugschluß Deinerseits. Dein Reader heißt Python und wird durch exec angestoßen. Dass Du das nicht erkannt hast, ist schonmal Dein erstes großes Problem damit. Durch exec kann irgendetwas passieren, was Dein Designer nicht abbildet.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Und Du hast anscheinend auch noch etwas nicht verstanden, dass mein Designer gar nichts abbildet, sondern direkt die Applikation bearbeitet. DynTkInter hat einen globalen Zustand, nämlich das ausgewählte Widget im ausgewählten Raum (Container). Und genau dieses ausgewählte Widget und den ausgewählten Raum kann der GUI Designer bearbeiten. Außerdem kann man mit dem Selektionsmodul in der Applikation oder Toplevel navigieren von Widget zu Widget von Raum zu Raum. Eine Abbildung der Applikation gibt es nicht, denn es wird hier die Original Applikation bearbeitet mittels Navigieren im Baum und Selektion des Widgets und Veränderung von dessen Attributen und indem man ein pack, grid oder place ausführt. Es werden auch fast keine Daten von den Widgets erfasst sondern jeweils direkt original von tkinter ausgelesen. Eines allerdings wird haargenau nachverfolgt, nämlich, welches Layout vorliegt, grid, place oder pack oder keines und wenn pack, dann in welcher Reihenfolge. Das meiste bei der Klasse GuiElement dreht sich um die Nachverfolgung des Layouts und hierfür sind die Methoden pack, grid und place, pack_forget, place_forget, grid_remove, grid_forget und was sonst noch damit zusammenhängt dementsprechend überschrieben bei den DynTkInter Widgets. Also nicht die Layout Daten selber, sondern nur welche Layout Art und evtl. in welcher Reihenfolge.Sirius3 hat geschrieben:@Alfons Mittelmeyer: das mit dem goIn und goOut ist doch nur ein traversieren des Baums. Würde das nicht auf globalen Zuständen operieren, wäre ist viel leichter zu verstehen. Dass Dein DynTk-Designer nichts liest, ist ein Trugschluß Deinerseits. Dein Reader heißt Python und wird durch exec angestoßen. Dass Du das nicht erkannt hast, ist schonmal Dein erstes großes Problem damit. Durch exec kann irgendetwas passieren, was Dein Designer nicht abbildet.
Keine Abbildung, sondern original Applikation.
Alles bekommt der GuiDesigner allerdings nicht mit. Wenn jemand zusätzliche Widgets statt von DynTkInter abzuleiten, von tkinter ableitet, die sind zwar sichtbar in der Applikation. Auswählbar und bearbeitbar sind sie allerdings nicht. Voraussetzung ist die Ableitung von DynTkInter.
Es kann auch jemand gerne eine ttk Treeview einbinden. Die ist dann eben auch sichtbar aber nicht bearbeitbar. Bleibt aber beim Abspeichern erhalten, da bei dem neuen Update nur die Klassendefinition bis erste Leerzeile nach __init__ bei vom GuiDesigner bearbeiteten Klassen ausgetauscht wird.
Ach so, eventuell sollte ich die Klassendefinition nicht mit austauschen, es könnte ja jemand die Containerklasse noch von einer weiteren Klasse herleiten wollen. Und ich sollte dann wohl wirklich nur die __init__ (bis erste Leerzeile) austauschen.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Also das mit JSON würde etwa so aussehen:
Wie das dann wirklich mit JSON aussieht:Also viel erkennt man da nicht mehr, weil alles dann nur mehr eine schwer unterscheidbare Struktur wird.
Da wäre wohl dann doch XML vorzuziehen. Und so sieht es mit XML aus:
Code: Alles auswählen
# statt
LabelFrame('button_frame',**{'text': 'Buttons', 'grid_cols': '(1, 75, 0, 0)', 'grid_rows': '(6, 25, 0, 0)'})
goIn()
Radiobutton('button_one',**{'text': 'One', 'underline': '0', 'anchor': 'w'}).grid(**{'sticky': 'ew', 'row': '1'})
goOut()
widget('button_frame').pack()
# mit JSON
{ 'button_frame':
[
{ 'class': 'LabelFrame',
'config': {'text': 'Buttons', 'grid_cols': '(1, 75, 0, 0)', 'grid_rows': '(6, 25, 0, 0)'},
'layout': [ 'pack' , 0 , {}],
'children' :
{
'button_one' :
[
{ 'class' : 'Radiobutton',
'config' : {'text': 'One', 'underline': '0', 'anchor': 'w'},
'layout' : [ 'grid' , {'sticky': 'ew', 'row': '1'}]
}
]
}
}
]
}
Code: Alles auswählen
{"button_frame": [{"layout": ["pack", 0, {}], "config": {"text": "Buttons", "grid_cols": "(1, 75, 0, 0)", "grid_rows": "(6, 25, 0, 0)"}, "class": "LabelFrame", "children": {"button_one": [{"layout": ["grid", {"row": "1", "sticky": "ew"}], "config": {"text": "One", "underline": "0", "anchor": "w"}, "class": "Radiobutton"}]}}]}
Da wäre wohl dann doch XML vorzuziehen. Und so sieht es mit XML aus:
Code: Alles auswählen
<?xml version="1.0" encoding="UTF-8" ?><root><button_frame type="list"><item type="dict"><layout type="list"><item type="str">pack</item><item type="int">0</item><item type="dict"></item></layout><config type="dict"><text type="str">Buttons</text><grid_cols type="str">(1, 75, 0, 0)</grid_cols><grid_rows type="str">(6, 25, 0, 0)</grid_rows></config><class type="str">LabelFrame</class><children type="dict"><button_one type="list"><item type="dict"><layout type="list"><item type="str">grid</item><item type="dict"><row type="str">1</row><sticky type="str">ew</sticky></item></layout><config type="dict"><text type="str">One</text><underline type="str">0</underline><anchor type="str">w</anchor></config><class type="str">Radiobutton</class></item></button_one></children></item></button_frame></root>
Zuletzt geändert von Alfons Mittelmeyer am Mittwoch 14. Oktober 2015, 17:50, insgesamt 1-mal geändert.
Mir ging es nicht darum zu beschreiben, wie Dein Designer funktioniert, sondern was einer aus meiner Sicht können sollte. So wie Du es bisher gebaut hast, ist es ein riesiger Monkey-Patch des Tk-Moduls.Alfons Mittelmeyer hat geschrieben:Jerch da täuscht Du Dich völlig darüber wie der GUI Designer arbeitet. Er lädt nichts, er greift nur auf die Widgets zu. Und wenn jemand mit einer Schleife Widgets erzeugt hat, dann sind sie da und können mit dem GUI Designer bearbeitet und gespeichert werden. ...
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Bist Du jetzt sauer oder was? Der Designer erfüllt genau Deine Anforderungen und übnertrifft sie sogar noch bei Weitem.jerch hat geschrieben:Mir ging es nicht darum zu beschreiben, wie Dein Designer funktioniert, sondern was einer aus meiner Sicht können sollte. So wie Du es bisher gebaut hast, ist es ein riesiger Monkey-Patch des Tk-Moduls.Alfons Mittelmeyer hat geschrieben:Jerch da täuscht Du Dich völlig darüber wie der GUI Designer arbeitet. Er lädt nichts, er greift nur auf die Widgets zu. Und wenn jemand mit einer Schleife Widgets erzeugt hat, dann sind sie da und können mit dem GUI Designer bearbeitet und gespeichert werden. ...
Deine Grundanfoderungen waren:
Also 'im Designer erstellte Oberflächen werden mit allen Deklarationen gespeichert'@Alfons:
Hmm, was sollte so ein Designer bzgl. Speichern/Laden können? Als Grundanforderung würde ich folgendes erwarten:
- im Designer erstellte Oberflächen werden mit allen Deklarationen gespeichert
- beim Laden ist alles im Designer Deklarierbare wieder zugänglich
Ein Bonbon gibts, wenn das Austauschformat auch noch texteditierbar ist, entweder direkt (dann brauchts ein Editor gängiges Format, welches alle deklarierbaren Zusammenhänge korrekt abbilden kann und für den Designer wieder parsbar ist) oder halt über eine Editorkomponente im Designer selbst (dann ginge auch ein Binärformat).
Das trifft zu und wird sogar noch übertroffen, denn auch nicht im Designer erstellte Widgets können im Designer bearbeitet und abgespeichert werden.
Und dann 'beim Laden ist alles im Designer Deklarierbare wieder zugänglich'
Auch das trifft vollständig zu. Lediglich man braucht nicht unbedingt etwas zu laden, denn statt dass der GUI Designer ein Script lädt, kann ein Programm auch den GuiDesigner laden.
Und 'Ein Bonbon gibts, wenn das Austauschformat auch noch texteditierbar ist, entweder direkt (dann brauchts ein Editor gängiges Format, welches alle deklarierbaren Zusammenhänge korrekt abbilden kann'
Auch das trifft zu, es ist ein leicht lesbares Format. Und damit meine ich nicht die exportierten Python Scripts, sondern die GUI Scripts, die man abspeichert.
Der Python Export ist ein Bonbon für die, welche ein solches Format wünschen. Und das Format mit Namen ist sogar wieder voll mit dem GuiDesigner ladbar, kann durch eigenen Code ergänzt werden und läßt sich dann auch in das tkinter Format - ohne Namen - mit dem dazu erstellen Code umwandeln.
Datei kopieren, GuiDesigner dazuladen, dann exportieren ohne Namen und beim import zu Beginn auf tkinter ändern und evtl. import DynTkExtent as ext mit dazu nehmen, falls erforderlich.
Und was hattest Du noch geschrieben, dass man ein Format braucht, das vom GuiDesigner parsbar ist. Nein, sondern man braucht lediglich ein Format, das tkinter Widgets erzeugt und wenn man statt tkinter DynTkInter nimmt, dann sind die Widgets für den GuiDesigner sichtbar und bearbeitbar. Die Frage wäre lediglich noch die wegen eines neutralen Formates. Am Besten würde man zuerst herumsehen, ob es so ein Format bereits für irgendwelche Programmiersprachen für tk gibt, bevor man ein XML tk Format für Python zusammenbastelt, das niemand benützen will.
Ich habe noch nicht gehört, dass jemand tkinter über XML programmieren möchte anstatt über direkten Funktionsaufruf.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Nun ja, es ist sicherlich sinnvoll, erst einmal zu recherchieren, ob und was es da so gibt. Aber die Prämisse ist falsch: Niemand "will" ein XML-Format benutzen oder darin direkt "programmieren", aber Dein Designer und ggf. ein mit dem Designer mitgeliefertes Modul zum dynamischen Erzeugen zur Laufzeit sollten es benutzen. Das reicht doch vollkommen aus!Alfons Mittelmeyer hat geschrieben:Am Besten würde man zuerst herumsehen, ob es so ein Format bereits für irgendwelche Programmiersprachen für tk gibt, bevor man ein XML tk Format für Python zusammenbastelt, das niemand benützen will.
Ich habe noch nicht gehört, dass jemand tkinter über XML programmieren möchte anstatt über direkten Funktionsaufruf.
Ich habe mir bei Qt noch nie einen anderen Designer gesucht bzw. ein anderes Werkzeugt außerhalb der offiziellen, geschweige denn in dem XML-Format manuell UI-Beschreibungsdateien erzeugt


Selbst wenn es im Bereich Tk noch nichts gängiges gibt, dürfte das also kein Grund sein, weswegen jemand *nicht* Deinen Designer einsetzen würde.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Ich habe mich umgeschaut. Niemand benutzt ein XML Format für tk. Weil es sich dabei um eine Programmiersprache handelt.Hyperion hat geschrieben:Nun ja, es ist sicherlich sinnvoll, erst einmal zu recherchieren, ob und was es da so gibt. Aber die Prämisse ist falsch: Niemand "will" ein XML-Format benutzen oder darin direkt "programmieren", aber Dein Designer und ggf. ein mit dem Designer mitgeliefertes Modul zum dynamischen Erzeugen zur Laufzeit sollten es benutzen. Das reicht doch vollkommen aus!
Außerdem bin ich auf etwas gestoßen. Mich hatte gewundert, dass man bei tkinter keine Namen benutzen kann und habe den Parent Children Baum dann mit Namen nachprogrammmiert. Aber in tcl tk benutzt man Namen. Man hat das dann bei tkinter und Python weggeworfen und stattdessen Referenzen eingeführt.
Das ist etwa tcl/tk Code:
Code: Alles auswählen
button ".b" -text "Say Hello" -command hello
pack ".b" -padx 20 -pady 6
Code: Alles auswählen
button(".b") -text("Say Hello") -command(hello);
pack(".b") -padx(20) -pady(6);
Das wäre natürlich Arbeit, denn bisher habe ich überhaupt keine Attribute hart programmiert, sondern sie nur abgefragt und dann auch wieder eingeben lassen. Allerdings eine Sortierreihenfolge habe ich dann hart programmiert - alles ist dabei wahrscheinlich noch nicht berücksichtigt.
So wäre man dann einigermassen unabhängig, wenn man sich am tk Format orientieren würde und dann die Besonderheiten Minus oder nicht, Klammern oder nicht bei Exporten für verschiedene Sprachen berücksichtigt. Allerdings möchte ich nicht gerne alle Attribute hart programmieren.
Warum mein Designer ein XML Format benutzen sollte, wenn das kein anderer benutzen will, verstehe ich allerdings nicht. Denn DynTkInter oder der GuiDesigner benutzen überhaupt keine Formate. Bei DynTkInter handelt es sich nur um erweiterte Widgets mit Baumstruktur, Selektion und Layout Type Infomation bzw. auch noch Namensverzeichnis bei Container Widgets. Und der GUI Designer ist nur eine Bedienoberfläche, die auf DynTkInter zugreift, damir er die Referenz auf das ausgewählte Widget bekommt. Außerdem modifiziert er Widgets, löscht er Widgets und legt neue an, versieht etwa auch Widgets mit Events, damit man sie mit der Maus bewegen kann. Das was dann im App Fenster zu zu Beginn nach sogenanntem Laden oder wie auch immer zu sehen ist, ist nichts, was der GUI Designer erzeugt, sondern entsteht durch Ausführung eines Python Scripts, entweder das der User selber gestartet hat und den GuiDesigner nachgeladen hat oder was über eine DynTkInter Funktion mittels read geladen und dann mit compile und eval ausgeführt wurde.
Wenn man also ein anderes Format haben will, dann ist das in Python zurückzuverwandeln und dann auszuführen. Denn auf irgendwelche Daten greifen DynTkInter und der GuiDesigner nicht zu, sondern nur auf vorhandene Widgets.
@Alfons Mittelmeyer: Fredrik Lund a.k.a. Effbot benutzt XML für Tkinter, der hat nämlich ein einfaches Beispiel dafür auf seinen Webseiten. Und Tk ist keine Programmiersprache sondern ein GUI-Toolkit. Die Programmiersprache die Du vielleicht meinst heisst Tcl.
Natürlich kann man Namen bei Tkinter benutzen. Daran bindet man die Objekte. Also ausser Dir macht das jeder so. Und auch in Tk-Anbindungen in anderen Programmiersprachen macht man das so.
Das C sieht wieder typisch nach Dir aus. Das sind keine API-Aufrufe der Tk-Bibliothek und da werden sinnloserweise die Rückgabewerte von Funktionsaufrufen voneinander abgezogen und mit dem Ergebnis wird dann nichts getan. Wie unsinnig ist das denn‽ Kannst/kennst Du überhaupt C? Das ganze in C würde eher mehr nach Tcl/Tk aussehen, denn das würde man in C sicher nicht in API-Aufrufen nachbasteln wenn man nicht gerade sehr viel Langeweile hat oder masochistisch veranlagt ist.
Natürlich kann man Namen bei Tkinter benutzen. Daran bindet man die Objekte. Also ausser Dir macht das jeder so. Und auch in Tk-Anbindungen in anderen Programmiersprachen macht man das so.
Das C sieht wieder typisch nach Dir aus. Das sind keine API-Aufrufe der Tk-Bibliothek und da werden sinnloserweise die Rückgabewerte von Funktionsaufrufen voneinander abgezogen und mit dem Ergebnis wird dann nichts getan. Wie unsinnig ist das denn‽ Kannst/kennst Du überhaupt C? Das ganze in C würde eher mehr nach Tcl/Tk aussehen, denn das würde man in C sicher nicht in API-Aufrufen nachbasteln wenn man nicht gerade sehr viel Langeweile hat oder masochistisch veranlagt ist.
@Alfons:
Gegeben sei ein Skript der Form:Wenn man dieses Skript in Deinen Designer lädt, sind die Buttons dann löschbar? Wenn Sie löschbar sind, was wird dann gelöscht und wo? Und was wird dann beim Speichern rausgeschrieben? Bitte den Inhalt der Datei einfach mal hier reinstellen oder mit Pseudocode illustrieren. Danke.
Gegeben sei ein Skript der Form:
Code: Alles auswählen
def create_fancy_dynbutton(some_argument):
# init & return button from dyn classes
dynbutton_object = DynButton()
return dynbutton_object
for i in range(3):
do_sumthing_with_button(create_fancy_button(i))
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Also jerch, da hast Du zuwenig geschrieben. Ich sehe nicht, wo die Widget Klasse DynButton definiert ist. Hat das überhaupt etwas mit tkinter zu tun? Also, wo ist Deine Definition für Dynbutton?jerch hat geschrieben:@Alfons:
Gegeben sei ein Skript der Form:Wenn man dieses Skript in Deinen Designer lädt, sind die Buttons dann löschbar? Wenn Sie löschbar sind, was wird dann gelöscht und wo? Und was wird dann beim Speichern rausgeschrieben? Bitte den Inhalt der Datei einfach mal hier reinstellen oder mit Pseudocode illustrieren. Danke.Code: Alles auswählen
def create_fancy_dynbutton(some_argument): # init & return button from dyn classes dynbutton_object = DynButton() return dynbutton_object for i in range(3): do_sumthing_with_button(create_fancy_button(i))
Also, wenn Du DynButton von tk.Button ableitest, oder ob es tk ist spielt keine Rolle, dann geht das. Und wenn Du tk durch import DynTkInter as tk importierst, dann hast Du anscheinend drei Buttons. Ob Du sie siehst, weiß ich nicht, da ich kein pack oder grid oder place sehe. Der Gui Designer kann sie aber trotzdem darstellen und Du kannst die Buttons dann löschen. Also bevor ich da irgend etwas illustriere, solltest Du zuerst Deine DynButton Klasse näher illustrieren.
Am Besten wäre, ein lauffähiges Beispiel hereinzustellen.
Außerdem ist es Unsinn, dynamisch erzeugte Widgets abzuspeichern, denn sonst hättest Du sie das nächste Mal doppelt. Ein Container Widget, das dynamisch generierte Widgets enthält, wäre also für die Abspeicherung von Widgets zu sperren.
Hier dazu das Modul 'SelectType.py' aus dem GUI Designer, das dynamisch generierte Widgets enthält, nämlich die Buttons für die Auswahl der zu kreierenden Widgetklasse:
Code: Alles auswählen
### CODE ===================================================
container().saveOnlyCode() # buttons are dynamically created, so the widgets shall not be saved. Only the code, which creates them shall be saved
index = 0
for widget_type in ("Message","Label","Button","Checkbutton","Radiobutton","Entry","Text","Spinbox","Scale","Listbox","Scrollbar","Frame","LabelFrame","PanedWindow","Canvas","Menu","Menubutton","Toplevel"):
Button(widget_type,text=widget_type,width=10) # Button with name and text of widget class
row,column = divmod(index,2) # position in 2 columns
rcgrid(row,column) # grid layout row,column
do_command(lambda msg = widget_type: send('CREATE_CLASS_SELECTED',msg)) # buttons send message with class name
index += 1 # increase index
### ========================================================
Hier der Ausschnitt aus dem GUI Designer:

Zuletzt geändert von Alfons Mittelmeyer am Donnerstag 15. Oktober 2015, 00:34, insgesamt 4-mal geändert.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
@jerch, ich weiss nicht, wie Du es haben willst.
Hab mal Deinen Code lauffähig genacht, wenn es Dir so recht ist, und den GuiDesigner dazu aufgerufen:Hab dann mit dem GuiDesigner ein Widget rausgelöscht und eines umbenannt, denn Python mag keine gleichen Namen und dann als tk ohne Namen exportiert und zwar in ein noch nicht vorhandenes File, also eine Neuanlage. Dabei bleibt kein bestehender Code erhalten:Hätte man auf einem File aufgebaut, der schon da gewesen wäre, wäre dort auch noch Dein Code vorhanden. Und das ist das gespeicherte Script. Da hätte ich eigentlich nichts umbenennen zu brauchen. denn mehrfach gleicher Name, ist diesem völlig egal:So sieht das Script aus, wenn man den Namen nicht ändert:Das Widget wird einfach (beim pack) indiziert adressiert. Hätte vielleicht einen unterschiedlichen text reinschreiben sollen, damit man sieht, ob die Reihenfolge auch stimmt. Aber sie stimmt, das weiß ich aus Erfahrung.
Hab mal Deinen Code lauffähig genacht, wenn es Dir so recht ist, und den GuiDesigner dazu aufgerufen:
Code: Alles auswählen
import DynTkInter as tk
root = tk.Tk()
class DynButton(tk.Button):
def __init__(self):
tk.Button.__init__(self,"DynButton",text='DynButton')
self.pack()
def do_sumthing_with_button(dummy): pass
def create_fancy_dynbutton(some_argument):
# init & return button from dyn classes
dynbutton_object = DynButton()
return dynbutton_object
for i in range(3):
do_sumthing_with_button(create_fancy_dynbutton(i))
root.mainloop('guidesigner/Guidesigner.py')
Code: Alles auswählen
import tkinter as tk
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
self.DynButton = tk.Button(self,**{'text': 'DynButton'})
self.DynButton02 = tk.Button(self,**{'text': 'DynButton'})
self.DynButton.pack()
self.DynButton02.pack()
Application().mainloop()
Code: Alles auswählen
Button('DynButton',**{'text': 'DynButton'})
Button('DynButton02',**{'text': 'DynButton'})
widget('DynButton').pack()
widget('DynButton02').pack()
Code: Alles auswählen
Button('DynButton',**{'text': 'DynButton'})
Button('DynButton',**{'text': 'DynButton'})
widget('DynButton',0).pack()
widget('DynButton',1).pack()
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
C typisch von mir? - außerdem ist es C++ Siehe http://cpptk.sourceforge.net/BlackJack hat geschrieben:@Alfons Mittelmeyer: Fredrik Lund a.k.a. Effbot benutzt XML für Tkinter, der hat nämlich ein einfaches Beispiel dafür auf seinen Webseiten. Und Tk ist keine Programmiersprache sondern ein GUI-Toolkit. Die Programmiersprache die Du vielleicht meinst heisst Tcl.
Natürlich kann man Namen bei Tkinter benutzen. Daran bindet man die Objekte. Also ausser Dir macht das jeder so. Und auch in Tk-Anbindungen in anderen Programmiersprachen macht man das so.
Das C sieht wieder typisch nach Dir aus. Das sind keine API-Aufrufe der Tk-Bibliothek und da werden sinnloserweise die Rückgabewerte von Funktionsaufrufen voneinander abgezogen und mit dem Ergebnis wird dann nichts getan. Wie unsinnig ist das denn‽ Kannst/kennst Du überhaupt C? Das ganze in C würde eher mehr nach Tcl/Tk aussehen, denn das würde man in C sicher nicht in API-Aufrufen nachbasteln wenn man nicht gerade sehr viel Langeweile hat oder masochistisch veranlagt ist.
Also C programmiere ich seit über 20 Jahren, da kann mir keiner etwas erzählen.
Und wo kann man in tkinter Namen benützen? In tcl/k schaut es so aus:
Code: Alles auswählen
button .dialog.ok
In tkinter sieht es so aus:
Code: Alles auswählen
ok = Button(dialog)
Soll man das als Namen benützen? Aber es gibt auch ok = Button(dialog, name="ok"). Wenn man dem Parent auch einen Namen gegen gat, kann man dann .dialog.ok als Namen benutzen, wenn man es beim Parent vergessen hat bekommt man so etwas wie .1428748.ok. Die name option ließe sich benützen, umbenennen kann man dann aber nichts mehr. Und mehrmals derselbe Name als child geht auch nicht. Quelle: http://www.scoberlin.de/content/media/h ... -names.htm
Ich denke, dass gleiche Namen, wie ich sie anbiete, auch nicht schlecht sind. Oder warum soll man sich den Kopf über einen Labelnamen zerbrechen, wenn man sowieso nur einen Text anzeigen will, aber nachher nichts mehr daran ändert und daher fünfmal einfach den Namen 'Label' kurz hintereinander im selbem Container benutzt? Außerdem haben bei mir die Widgets gar keinen Namen, nur die Verzeichniseinträge für die Widgets haben einen Namen.
Und was meinst Du damit? 'Das sind keine API-Aufrufe der Tk-Bibliothek und da werden sinnloserweise die Rückgabewerte von Funktionsaufrufen voneinander abgezogen und mit dem Ergebnis wird dann nichts getan.'
Da sieht man wohl, wer nichts von C++ versteht und dann dazu noch anderen Sinnloses unterstellen will. Das Beispiel war auch nicht von mir, wie bereits vorher erwähnt. Und hier wird nichts abgezogen, sondern das sind Funktionsaufrufe. In C++ kann man nämlich Operatoren und natürlich auch den - Operator abhängig vom Operanden überschreiben, dass der etwas ganz anderes tut. In Python aber geht das wohl nicht. Also mal ein wenig mit C++ und dem Überschreiben von Operatoren befassen, bevor man andere angreifen will.
@Alfons Mittelmeyer: Du schreibst „Und so sieht es in C aus:“ und zeigst dann etwas das in C so niemand schreiben würde und fährst mir dann an den Karren das ich keine Ahnung von C++ habe und Dir das selbe unterstellen wollte? Geht's noch?
(Ich programmiere in C und Python seit über 20 Jahren — und nun?)
Mit 'Das sind keine API-Aufrufe der Tk-Bibliothek und da werden sinnloserweise die Rückgabewerte von Funktionsaufrufen voneinander abgezogen und mit dem Ergebnis wird dann nichts getan.' meine ich genau das was da steht: Das ist kein C und das sieht man ganz deutlich. Dass es C sei hattest Du behauptet. Ich habe genug Ahnung von C++ das ich weiss das es dort Operatorüberladung gibt. In C aber nicht. Und die C-API sind nun mal deutlich anders aus. Da würde man den Grossteil mit Zeichenketten mit Tcl/Tk und `Tk_Eval()` oder einer der verwandten Funktionen abwickeln weil das in C-API-Aufrufen sonst sehr umständlich und schwer lesbar wird.
Man soll nicht die Zeichenkette '.1428748.1432920' als Namen benutzen, denn das ist für Python kein Name, sondern `ok`. Das ist ein Name. Den kann und sollte man benutzen, denn genau dafür sind Namen ja da. Die `name`-Option braucht man normalerweise nicht und die generierten Namen interessieren normalerweise nicht. Du siehst und löst glaube ich schon wieder Probleme die nur in Deinem Kopf existieren, beziehungsweise weil Du an die Sache so unorthodox herangehen willst und die API nicht so verwendest wie das vorgesehen ist.
Wenn man keinen Namen benötigt, wie im `Label`-Fall das nur einmal erzeugt wird ohne das man später noch mal darauf zugreifen möchte, bindet man das Objekt einfach an *keinen* Namen. Schon hat sich die Frage erübrigt ob man auch den gleichen Namen für so etwas mehrfach verwenden kann.
(Ich programmiere in C und Python seit über 20 Jahren — und nun?)
Mit 'Das sind keine API-Aufrufe der Tk-Bibliothek und da werden sinnloserweise die Rückgabewerte von Funktionsaufrufen voneinander abgezogen und mit dem Ergebnis wird dann nichts getan.' meine ich genau das was da steht: Das ist kein C und das sieht man ganz deutlich. Dass es C sei hattest Du behauptet. Ich habe genug Ahnung von C++ das ich weiss das es dort Operatorüberladung gibt. In C aber nicht. Und die C-API sind nun mal deutlich anders aus. Da würde man den Grossteil mit Zeichenketten mit Tcl/Tk und `Tk_Eval()` oder einer der verwandten Funktionen abwickeln weil das in C-API-Aufrufen sonst sehr umständlich und schwer lesbar wird.
Man soll nicht die Zeichenkette '.1428748.1432920' als Namen benutzen, denn das ist für Python kein Name, sondern `ok`. Das ist ein Name. Den kann und sollte man benutzen, denn genau dafür sind Namen ja da. Die `name`-Option braucht man normalerweise nicht und die generierten Namen interessieren normalerweise nicht. Du siehst und löst glaube ich schon wieder Probleme die nur in Deinem Kopf existieren, beziehungsweise weil Du an die Sache so unorthodox herangehen willst und die API nicht so verwendest wie das vorgesehen ist.
Wenn man keinen Namen benötigt, wie im `Label`-Fall das nur einmal erzeugt wird ohne das man später noch mal darauf zugreifen möchte, bindet man das Objekt einfach an *keinen* Namen. Schon hat sich die Frage erübrigt ob man auch den gleichen Namen für so etwas mehrfach verwenden kann.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Also wenn jemand so ein Format haben möchte, kann ich das schon irgendwann einmal machen. Aber es ist nicht Bestandteil dieser ersten Version:
Code: Alles auswählen
<?xml version="1.0" encoding="UTF-8" ?><root><button_frame type="list"><item type="dict"><layout type="list"><item type="str">pack</item><item type="int">0</item><item type="dict"></item></layout><config type="dict"><text type="str">Buttons</text><grid_cols type="str">(1, 75, 0, 0)</grid_cols><grid_rows type="str">(6, 25, 0, 0)</grid_rows></config><class type="str">LabelFrame</class><children type="dict"><button_one type="list"><item type="dict"><layout type="list"><item type="str">grid</item><item type="dict"><row type="str">1</row><sticky type="str">ew</sticky></item></layout><config type="dict"><text type="str">One</text><underline type="str">0</underline><anchor type="str">w</anchor></config><class type="str">Radiobutton</class></item></button_one></children></item></button_frame></root>
Hi Alfons
Habe das Projekt mit save gespeichert:
Habe das Projekt exportiert mit With Names:
Habe das Projekt exportiert mit Without Names:
Habe jedes der beiden Skripts (With Names & Without Names) ausgeführt. In beiden Fällen wurde ein Gui-Fenster mit nur einem Button angezeigt. Habe das Skript Without Names mit Geany wie folgt abgeändert:
Also habe unmittelbar nach Erstellung der Instanz des Wigets (Button) die Zeile für die Festlegung des Layouters pack angefügt. Mit der Ausführung des geänderten Skripts werden jetzt wieder alle untereinander liegenden Buttons angezeigt.
Fazit:
Bei mehreren nacheinander folgenden Widgets mit gleichen Instanznamen muss die Zeile für den Layouter unmittelbar nach dem Widget folgen.
Gruss wuf
Ich startete dein obiges Skript. Der DynTk-Designer öffnete sich automatisch und es wurde das Gui-Fenster mit den drei untereinander liegenden Buttons angezeigt.Alfons Mittelmeyer hat geschrieben:Code: Alles auswählen
import DynTkInter as tk root = tk.Tk() class DynButton(tk.Button): def __init__(self): tk.Button.__init__(self,"DynButton",text='DynButton') self.pack() def do_sumthing_with_button(dummy): pass def create_fancy_dynbutton(some_argument): # init & return button from dyn classes dynbutton_object = DynButton() return dynbutton_object for i in range(3): do_sumthing_with_button(create_fancy_dynbutton(i)) root.mainloop('guidesigner/Guidesigner.py')
Habe das Projekt mit save gespeichert:
Code: Alles auswählen
Button('DynButton',**{'text': 'DynButton'})
Button('DynButton',**{'text': 'DynButton'})
Button('DynButton',**{'text': 'DynButton'})
widget('DynButton',0).pack()
widget('DynButton',1).pack()
widget('DynButton',2).pack()
Code: Alles auswählen
import DynTkInter as tk
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
self.DynButton = tk.Button((self,'DynButton'),**{'text': 'DynButton'})
self.DynButton = tk.Button((self,'DynButton'),**{'text': 'DynButton'})
self.DynButton = tk.Button((self,'DynButton'),**{'text': 'DynButton'})
self.DynButton.pack()
self.DynButton.pack()
self.DynButton.pack()
Application().mainloop()
Code: Alles auswählen
import tkinter as tk
import DynTkExtend as ext
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
self.DynButton = tk.Button(self,**{'text': 'DynButton'})
self.DynButton = tk.Button(self,**{'text': 'DynButton'})
self.DynButton = tk.Button(self,**{'text': 'DynButton'})
self.DynButton.pack()
self.DynButton.pack()
self.DynButton.pack()
Application().mainloop()
Code: Alles auswählen
import tkinter as tk
import DynTkExtend as ext
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
self.DynButton = tk.Button(self,**{'text': 'DynButton'})
self.DynButton.pack()
self.DynButton = tk.Button(self,**{'text': 'DynButton'})
self.DynButton.pack()
self.DynButton = tk.Button(self,**{'text': 'DynButton'})
self.DynButton.pack()
Application().mainloop()
Fazit:
Bei mehreren nacheinander folgenden Widgets mit gleichen Instanznamen muss die Zeile für den Layouter unmittelbar nach dem Widget folgen.
Gruss wuf

Take it easy Mates!
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
@ Hi wuf,
ist klar, dass Da nur immer ein Button zu sehen ist. Denn es ist dreimal derselbe Name. Da wird dann immer nur derselbe Button gepackt.
Du verstehts doch, dass dreimal der gleiche Name in Python nichts bringt, oder?
Ich könnte natürlich auch veränderte Namen vergeben, indem ich etwa _1, _2,_3 hinzufüge, oder soll der Anwender selber aufpassen?
Ich könnte natürlich die Buttons auch, bevor ich sie erzeuge, gleich richtig nach der pack-Reihenfolge sortieren, damit ich gleich im Anschluß das pack ausgeben kann.
Was wäre da sinnvoll?
Wenn jemand bequem ist und für Labels die gleichen Namen verwendet, die dann aber nachher nicht mehr ansprechen will, wäre vielleicht die richtige Sortierung die richtige Lösung?
Was meinst Du?
ist klar, dass Da nur immer ein Button zu sehen ist. Denn es ist dreimal derselbe Name. Da wird dann immer nur derselbe Button gepackt.
Du verstehts doch, dass dreimal der gleiche Name in Python nichts bringt, oder?
Ich könnte natürlich auch veränderte Namen vergeben, indem ich etwa _1, _2,_3 hinzufüge, oder soll der Anwender selber aufpassen?
Ich könnte natürlich die Buttons auch, bevor ich sie erzeuge, gleich richtig nach der pack-Reihenfolge sortieren, damit ich gleich im Anschluß das pack ausgeben kann.
Was wäre da sinnvoll?
Wenn jemand bequem ist und für Labels die gleichen Namen verwendet, die dann aber nachher nicht mehr ansprechen will, wäre vielleicht die richtige Sortierung die richtige Lösung?
Was meinst Du?
Hi Alfons
Gruss wuf
Das ist mir sehr wohl klar. Wollte nur zeigen, dass trotz den drei gleichen Objektnamen drei diskrete Buttons dargestellt werden. Übrigens spielt der Name keine Rolle wenn du auch 100 von diesen Buttonobjekten in einer Liste speicherst und dann über den zugehörigen Index auf sie zugreifst.Alfons Mittelmeyer hat geschrieben:Du verstehts doch, dass dreimal der gleiche Name in Python nichts bringt, oder?
Gruss wuf

Take it easy Mates!
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
@ Hi wuf,
den Index biete ich aber für den Export nicht an. Die richtige Lösung wäre wohl eine Sortierung in der richtigen Packreihenfolge mit gleich anschließendem pack.
Wenn jemand dann einen Callback draufsetzen will, sollte er langsam draufkommen, dass er dieselbe Variable genommen hat.
Aber wenn jemand nur Labels ohne Callback hat, braucht er dann keine unterschiedlichen Namen vergeben.
Einfach Namen verändern, wie ich es bei DynAccess gemacht habe, möchte ich ungern, weil der User das evtl nicht möchte, wenn ich das einfach mache, ohne zu fragen.
Und wenn man das gleich richtig sortiert:Dann bekommt man das:Und dann steht einer Konvertierung nach JSON auch kaum mehr etwas im Wege.
den Index biete ich aber für den Export nicht an. Die richtige Lösung wäre wohl eine Sortierung in der richtigen Packreihenfolge mit gleich anschließendem pack.
Wenn jemand dann einen Callback draufsetzen will, sollte er langsam draufkommen, dass er dieselbe Variable genommen hat.
Aber wenn jemand nur Labels ohne Callback hat, braucht er dann keine unterschiedlichen Namen vergeben.
Einfach Namen verändern, wie ich es bei DynAccess gemacht habe, möchte ich ungern, weil der User das evtl nicht möchte, wenn ich das einfach mache, ohne zu fragen.
Und wenn man das gleich richtig sortiert:
Code: Alles auswählen
Button('DynButton',**{'text': 'DynButton'})
Button('DynButton',**{'text': 'DynButton'})
Button('DynButton',**{'text': 'DynButton'})
widget('DynButton',0).pack()
widget('DynButton',1).pack()
widget('DynButton',2).pack()
Code: Alles auswählen
Button('DynButton',**{'text': 'DynButton'}).pack()
Button('DynButton',**{'text': 'DynButton'}).pack()
Button('DynButton',**{'text': 'DynButton'}).pack()
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Muss aber noch über eine Lösung nachdenken, denn dabei beißt sich wieder etwas. Bei gleichen Namen werden die Widgets hintereinander erzeugt, damit die Reihenfolge und der Index erhalten bleiben.
Wenn man allerdings diese Reihenfolge durch die Packreihenfolge stört, kommt dieser Index durcheinander.
Die andere Frage wäre natürlich, ob jemand diesen Index tatsächlich benutzen will und darauf Callbacks programmmiert und dann andererseits ein exportiertes Script mit Namen wieder in den GuiDesigner lädt. Vielleicht fällt mir doch noch eine Lösung ein.
Aber es geht ja nur um den Variablennamen und nicht um den Widgetnamen. Also sollte ich doch den Variablennamen verändern bei gleichem Widgetnamen.
Wenn man allerdings diese Reihenfolge durch die Packreihenfolge stört, kommt dieser Index durcheinander.
Die andere Frage wäre natürlich, ob jemand diesen Index tatsächlich benutzen will und darauf Callbacks programmmiert und dann andererseits ein exportiertes Script mit Namen wieder in den GuiDesigner lädt. Vielleicht fällt mir doch noch eine Lösung ein.
Aber es geht ja nur um den Variablennamen und nicht um den Widgetnamen. Also sollte ich doch den Variablennamen verändern bei gleichem Widgetnamen.
Zuletzt geändert von Alfons Mittelmeyer am Donnerstag 15. Oktober 2015, 11:46, insgesamt 1-mal geändert.