Sirius3 hat geschrieben:Was Du da in create_menu löschen mußt, ist mir ein Rätsel. In einem neu erzeugten Widget sollte man eigentlich nichts löschen können/müssen.
Man kann natürlich etwas für eine Bestimmte Anzahl von Sprachen machen, etwa einige aus Europa. Es könnten aber auch mehr werden, eventuell kommt Asien auch dazu mit einer unterschiedlichen Sprachenanzahl.
So ist das Menü voll flexibel. Es wird eine Liste übergeben, egal wie kurz oder lang und das Menü baut sich entsprechend der Liste neu auf. Und wenn man etwa activebackground oder sonst etwas an den commands ändern will, braucht man das nur beim ersten tun. Der erste bleibt fix, wobei sich auch der Text ändert, das Aussehen er anderen, die dynamisch erzeugt werden, richtet sich danach!
Sirius3 hat geschrieben: Zeile 77: das continue durch ein else ersetzen. Die variablen Teile von add_command übergibt man als Keywords und ändert nicht das Wörterbuch in jedem Schleifendurchgang
Wie willst Du das Wörterbuch durch Keywords von etwas ändern, das von etwas ändern, das gar nicht noch nicht existiert? Das Wörtebuch stamt vom ersten command und darin wird der label und der command geändert!
Sirius3 hat geschrieben:Einen Wörterbucheintrag erst zu lesen und dann zu poppen ist irgendwie umständlich.
Ja finde iich auch, bei entryconfig bekommt man dumme border objects, etwa so:
'background': ('background', '', '', '', <border object: 'white'>)
Wenn man das liest mit entryconfig, bekommt man 'white'.
Das shorten dagegen hate ich bei config und layouts gemacht, ist aber hier in diesem Fallö überflüssig, darauf hatte ich nicht geachtet, dass ich das hier gar nicht brauche.
Nö, ich brauche es dooch, weil ich dann so eine Fehlermeldung bekomme: bitmap "{}" not defined
Sirius3 hat geschrieben:get_entryconfig bekommt einen index, der aber gar nicht benutzt wird.
Das ist Unsinn, der ist ganz wichtig und wird benutzt bei: menu.entrycget(index,entry)
Sirius3 hat geschrieben:communication.py enthält nur irgendwelche seltsamen globalen Variablen, das muß also weg.
Nein das sind zwei Funktionen, und nur über die ist das Zusammenspiel von Teilen möglich alled andere muss sweg, außer den Widget und Namenlosen Klassen, für die es kein Objekt gibt, und auf die sonst nicht zugreifen kann.
Der Code sieht dann so aus:
def noname1:
def __init__(self,ref_to_widget,ref_to_widget..) # aber nur im selben container (Frame, oder Menu, oder App oder Toplevel, etc.)
...
noname1()
Und nach der Definition werden die sofort aufgerufen und das war es dann ohne die Funktionen subcribe und publish läuft fast gar nichts, höchstens dass eine Betätigung eines Buttons etwas anderes im selben container verändern könnte aber ohne jeglichen Bezug zu außen. Und genau das ist der Sinn, unabhängige Teile, die ganz egal irgenwo stehen könnte, die man einfach jederzeit umverlagern kann und bei denen man nicht verschiedenen Code zu einem Wirrwarr vermischen kann.
Sirius3 hat geschrieben:Und die letzte Datei möchte keiner haben. Gemisch aus globalen Anweisungen und Klassendefinitionen.
Nein es geht nicht um Klassendefinitionen, sondern nur um einen Aufruf, die Klassen sind innerhalb von Funktionen völlig unbekannt und dienen nur dazu, bei der Initialisiereung auch einen Code aufzurufen. Das ist mit einer Klasse einfacher, weil man bei einer Funktion nur auf rückwärts Bezug nehmen kann, bei einer Klasse aber auch vorwärts. Ansonsten wäre eine Klasse unnötig.
Na als Enresultat möchte wahrscheinlich niemand solchen Code haben. Aber als Zwischensfufe ist er ideal. Man ,kann den Code beliebig umverlagern und zerteilen, etwa das:
Code: Alles auswählen
config(myclass='BOStrab_Fahrzeugeinschraenkung')
Menu('MainMenu',myclass='MenuGUI')
goIn()
MenuItem('languages','cascade',label='Sprachen')
goIn()
Menu('language_submenu',myclass='LanguageSubmenu', tearoff=0)
goIn()
MenuItem('deutsch','command',label='deutsch')
widget('deutsch').layout(index=1)
### CODE ===================================================
class LanguageSubmenu:
def __init__(self):
self._start()
self._dont_save_dynamically_created()
def _start(self,container = container()):
self.container = container
self.deutsch_index = self.container['tearoff']
self._create_menu()
def _create_menu(self):
current_selection = Selection()
self.create_menu()
setSelection(current_selection)
# here should follow own code in tkinter style
# later the GuiDesigner should be able to export this code
# EXPORT =============================
def create_menu(self):
self.container.add_checkbutton()
# now we delete the menu entries after deutsch
after_deutsch = self.deutsch_index + 1
while True:
itemtype = self.container.type(after_deutsch)
self.container.delete(after_deutsch)
if itemtype == 'checkbutton':
break
command_config = get_entryconfig(self.container,self.deutsch_index)
languages = ('deutsch','english','russisch','polnisch','italienisch',None,'spanisch','französisch',None,'dänisch')
for index,language in enumerate(languages):
if not language:
self.container.add_separator()
continue
command_config['label'] = language
command_config['command'] = partial(self.do_action,language)
try:
self.container.entryconfig(index+self.deutsch_index,**command_config)
except IndexError:
self.container.add_command(**command_config)
def do_action(self,language):
publish("SELECT_LANGUAGE",language)
# /EXPORT =============================
# we don't want to save dynamically created widgets after self.deutsch_index by the GuiDesigner
def _dont_save_dynamically_created(self):
start_index = self.deutsch_index - self.container['tearoff']
for element in self.container.PackList[start_index+1:]:
element.dontSave()
LanguageSubmenu()
### ========================================================
goOut()
select_menu()
goOut()
widget('languages').layout(index=1)
goOut()
select_menu()
Zerteilt man in das:
Code: Alles auswählen
config(myclass='BOStrab_Fahrzeugeinschraenkung')
Menu('MainMenu',myclass='MenuGUI')
goIn()
MenuItem('languages','cascade',label='Sprachen')
goIn()
Menu('language_submenu',link='Scripts/languages.py').select_menu()
goOut()
widget('languages').layout(index=1)
goOut()
select_menu()
Das interessiert aber nicht weiter, denn das sind nur die Widgets und Widget directories für den gui designer.
Und in das:
Code: Alles auswählen
config(myclass='LanguageSubmenu', tearoff=0)
MenuItem('deutsch','command',label='deutsch')
widget('deutsch').layout(index=1)
### CODE ===================================================
class LanguageSubmenu:
def __init__(self):
self._start()
self._dont_save_dynamically_created()
def _start(self,container = container()):
self.container = container
self.deutsch_index = self.container['tearoff']
self._create_menu()
def _create_menu(self):
current_selection = Selection()
self.create_menu()
setSelection(current_selection)
# EXPORT =============================
def create_menu(self):
# now we delete the menu entries after deutsch
self.container.add_checkbutton()
after_deutsch = self.deutsch_index + 1
while True:
itemtype = self.container.type(after_deutsch)
self.container.delete(after_deutsch)
if itemtype == 'checkbutton':
break
command_config = get_entryconfig(self.container,self.deutsch_index)
languages = ('deutsch','english','russisch','polnisch','italienisch',None,'spanisch','französisch',None,'dänisch')
for index,language in enumerate(languages):
if not language:
self.container.add_separator()
continue
command_config['label'] = language
command_config['command'] = partial(self.do_action,language)
try:
self.container.entryconfig(index+self.deutsch_index,**command_config)
except IndexError:
self.container.add_command(**command_config)
def do_action(self,language):
publish("SELECT_LANGUAGE",language)
# /EXPORT =============================
# we don't want to save dynamically created widgets after self.deutsch_index by the GuiDesigner
def _dont_save_dynamically_created(self):
start_index = self.deutsch_index - self.container['tearoff']
for element in self.container.PackList[start_index+1:]:
element.dontSave()
LanguageSubmenu()
### ========================================================
Und auf diesen Code kann man sich, dann ohne alles Beiwerk voll konzentrieren, kann nichts anderes hineinmischen, und dann fällt einem ein, dass ja die language Liste empfangen werden muss und macht dann eine entsprechene Methode unter Benutzung von subscribe hinein. Wenn später ein Sender hierfür implementiert ist, dann tut sich auch etwas. Dem Programm fehlt nichts, es ist immer lauffähig, nur ohne Sender, tut es nicht viel.
Und genau darum geht es, immer ein lauffähiges Programm haben und die Funktionalität ohne Nebenwirkungen auf Anderes erweitern.
PS: Und dann muss die Sprachliste jeweils ein Tuple haben nämlich die Sprache, die angezeigt werden soll und die Sprachidentität, eventuell da bei Englisch bleiben.