Seite 1 von 2
Dynamische Generierung von Eingabemasken
Verfasst: Montag 26. Juni 2017, 18:42
von Alfons Mittelmeyer
Dieses Thema wurde an mich herangetragen und ist wohl des Behandelns wert.
Also, es gibt eine Funktion oder Methode. Diese erhält ein Objekt übergeben, aus dem eine Eingabemaske erstellt werden soll.
Das wäre der Ausgangspunkt:
Code: Alles auswählen
# -*- coding: utf-8 -*-
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
# widget definitions ===================================
self.Eingabemaske = Eingabemaske(self)
self.Eingabemaske.pack(fill='x')
class Eingabemaske(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
self.config(text='Eingabemaske')
# widget definitions ===================================
self.content = tk.Frame(self)
self.content.pack(fill='x')
if __name__ == '__main__':
Application().mainloop()
Doch wie geht das jetzt weiter?
Re: Dynamische Generierung von Eingabemasken
Verfasst: Montag 26. Juni 2017, 19:06
von __deets__
Ich sehe da nichts, das irgendwem irgendwie uebergeben wird - zumindest bezogen auf die Aufgabenstellung.
Da wirst du schon noch etwas mehr ausholen muessen.
Re: Dynamische Generierung von Eingabemasken
Verfasst: Montag 26. Juni 2017, 19:18
von stefanxfg
Dann nimm mal diese GUI. Es handelt sich um eine Tabelle. Diese soll eine Stadardtabellenform darstellen. Der Inhalt, bestehend aus Label und Entry, kann von der Anzahl der Zeilen variieren.
Der Sinn ist, die Standardform an verschiedenen Stellen der GUI einzfügen und dynamisch die Zeilen zu erzeugen. Ich denke da an Dictionaries für die Labels und davon abhängig die Zeilen zu erstellen.
Code: Alles auswählen
# -*- coding: utf-8 -*-
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
#import DynTkInter as tk # for GuiDesigner
# === general grid table definition =================
def grid_general_rows(container,rows,**kwargs):
for row in range(rows):
container.rowconfigure(row,**kwargs)
def grid_general_cols(container,columns,**kwargs):
for column in range(columns):
container.columnconfigure(column,**kwargs)
# Application definition ============================
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
self.title('APP')
self.geometry('1263x75+76+111')
self.minsize(116, 1)
self.maxsize(1444, 882)
# individual grid definition ===========================
self.rowconfigure(0,minsize=25, pad=0, weight=0)
self.columnconfigure(0,minsize=75, pad=0, weight=1)
# widget definitions ===================================
self.MAINFRAME = MainFrame(self,name='#0_MAINFRAME')
self.MAINFRAME.grid(row=0, sticky='nesw')
class MainFrame(tk.Frame):
def __init__(self,master,**kwargs):
tk.Frame.__init__(self,master,**kwargs)
self.myclass = 'MainFrame'
# general grid definition ==============================
grid_general_rows(self,2, minsize = 25, pad = 0, weight = 0)
grid_general_cols(self,1, minsize = 0, pad = 0, weight = 1)
# individual grid definition ===========================
self.columnconfigure(0,minsize=75, pad=0, weight=1)
# widget definitions ===================================
self.TitleFrame = Titleframe(self,name='#1_TitleFrame')
self.TitleFrame.grid(row=0, sticky='ew')
self.ContentFrame = ContentFrame(self,name='#2_ContentFrame')
self.ContentFrame.grid(row=1, sticky='ew')
class ContentFrame(tk.Frame):
def __init__(self,master,**kwargs):
tk.Frame.__init__(self,master,**kwargs)
self.myclass = 'ContentFrame'
# general grid definition ==============================
grid_general_cols(self,3, minsize = 0, pad = 0, weight = 1)
# individual grid definition ===========================
self.rowconfigure(0,minsize=25, pad=0, weight=0)
self.columnconfigure(0,minsize=0, pad=0, weight=0)
self.columnconfigure(1,minsize=0, pad=0, weight=0)
self.columnconfigure(2,minsize=0, pad=100, weight=20)
# widget definitions ===================================
self.Bezeichnung = tk.Label(self,name='#3_Bezeichnung',anchor='w', justify='left', text='label', width=50)
self.Bezeichnung.grid(row=0, sticky='nsw')
self.entry = tk.Entry(self,name='#4_entry')
self.entry.grid(column=2, row=0, sticky='nesw')
class Titleframe(tk.Frame):
def __init__(self,master,**kwargs):
tk.Frame.__init__(self,master,**kwargs)
self.myclass = 'Titleframe'
# individual grid definition ===========================
self.rowconfigure(0,minsize=25, pad=0, weight=0)
self.columnconfigure(0,minsize=75, pad=0, weight=1)
# widget definitions ===================================
self.label = tk.Label(self,name='#5_label',anchor='w', fg='#0000FF', text='label', width=25)
self.label.grid(row=0, sticky='nesw')
if __name__ == '__main__':
#Application().mainloop('guidesigner/Guidesigner.py') # for GuiDesigner
Application().mainloop()
Re: Dynamische Generierung von Eingabemasken
Verfasst: Montag 26. Juni 2017, 20:04
von Alfons Mittelmeyer
__deets__ hat geschrieben:Ich sehe da nichts, das irgendwem irgendwie uebergeben wird - zumindest bezogen auf die Aufgabenstellung.
Da wirst du schon noch etwas mehr ausholen muessen.
Ja stimmt, da wurde noch nichts übergeben. Daher müssen wir die Klasse entwickeln, die übergeben wird. Und ich denke, die ist schon einmal für den Anfang nicht schlecht.
Wir können da ein eigenes Dictionary verwenden oder auch eines von außerhalb:
Code: Alles auswählen
# -*- coding: utf-8 -*-
class Input_Class:
def __init__(self,get_dictionary=None):
if get_dictionary:
self.get_dictionary = get_dictionary
else:
self.dictionary = {
'Name': '',
'Vorname': '',
'Straße': '',
'Hausnummer':'',
'PLZ':'',
'Ort':'',
}
self.get_dictionary = self.get_own_dictionary
def get_own_dictionary(self):
return self.dictionary
def keys(self):
pass
Input_Object = Input_Class()
print(Input_Object.get_dictionary())
Und was nicht schlecht ist, genau dieselbe Klasse mit exakt dem gleichen Code läßt sich auch in diesem Zusammenhang einsetzen:
Code: Alles auswählen
# -*- coding: utf-8 -*-
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class Input_Class:
def __init__(self,get_dictionary=None):
if get_dictionary:
self.get_dictionary = get_dictionary
else:
self.dictionary = {
'Name': '',
'Vorname': '',
'Straße': '',
'Hausnummer':'',
'PLZ':'',
'Ort':'',
}
self.get_dictionary = self.get_own_dictionary
def get_own_dictionary(self):
return self.dictionary
def keys(self):
pass
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
# widget definitions ===================================
self.Eingabemaske = Eingabemaske(self)
self.Eingabemaske.pack(fill='x')
Input_Object = Input_Class(self.Eingabemaske.config_dictionary)
print(Input_Object.get_dictionary())
class Eingabemaske(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
self.config(text='Eingabemaske')
# widget definitions ===================================
self.content = tk.Frame(self)
self.content.pack(fill='x')
def config_dictionary(self):
dictionary = self.config()
dictionary2 = {}
for element in dictionary:
dictionary2[element] = str(self[element])
return dictionary2
if __name__ == '__main__':
Application().mainloop()
Das war natürlich nicht gut jetzt
Verfasst: Montag 26. Juni 2017, 20:35
von Alfons Mittelmeyer
Denn es soll in diesem Fall für jede Art von Widgets gehen:
Code: Alles auswählen
# -*- coding: utf-8 -*-
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class Input_Class:
def __init__(self,get_dictionary=None):
if get_dictionary:
self.get_dictionary = get_dictionary
else:
self.dictionary = {
'Name': '',
'Vorname': '',
'Straße': '',
'Hausnummer':'',
'PLZ':'',
'Ort':'',
}
self.get_dictionary = self.get_own_dictionary
def get_own_dictionary(self):
return self.dictionary
def keys(self):
pass
class Widget_Config:
def __init__(self,widget):
self.widget = widget
def config_dictionary(self):
dictionary = self.widget.config()
dictionary2 = {}
for element in dictionary:
dictionary2[element] = str(self.widget[element])
return dictionary2
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
# widget definitions ===================================
self.Eingabemaske = Eingabemaske(self)
self.Eingabemaske.pack(fill='x')
Input_Object = Input_Class(Widget_Config(self.Eingabemaske).config_dictionary)
print(Input_Object.get_dictionary())
class Eingabemaske(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
self.config(text='Eingabemaske')
# widget definitions ===================================
self.content = tk.Frame(self)
self.content.pack(fill='x')
if __name__ == '__main__':
Application().mainloop()
Komisch ist dabei aber, dass ich hier keine Hausnummer sehe
Wichtig ist eine sortierte Liste
Verfasst: Montag 26. Juni 2017, 20:52
von Alfons Mittelmeyer
Ein Dictionary ist ungeordnet. SWichtig istm, dass unsewre Maske geordnet aufgebaut ist. Deshalb soll unsere Klasse eine sortierte key Liste liefern:
Code: Alles auswählen
# -*- coding: utf-8 -*-
class Input_Class:
def __init__(self,get_dictionary=None):
if get_dictionary:
self.get_dictionary = get_dictionary
else:
self.dictionary = {
'Name': '',
'Vorname': '',
'Straße': '',
'Hausnummer':'',
'PLZ':'',
'Ort':'',
}
self.get_dictionary = self.get_own_dictionary
def get_own_dictionary(self):
return self.dictionary
def keys(self):
return [ 'Name',
'Vorname',
'Straße',
'Hausnummer',
'PLZ',
'Ort',
]
def __getitem__(self,key):
return self.get_dictionary()[key]
Input_Object = Input_Class()
keys = Input_Object.keys()
for key in keys:
print(key,Input_Object[key])
Re: Dynamische Generierung von Eingabemasken
Verfasst: Montag 26. Juni 2017, 21:08
von stefanxfg
Hallo Alfons,
verstehe ich das richtig, dass du aus dem dictionary eine labelliste machen willst, die du dann zur gui erzeugst?
Vielleicht noch das zuvor
Verfasst: Montag 26. Juni 2017, 21:09
von Alfons Mittelmeyer
Abhängig vom gewählten Layout und wenn es auf den Platz ankommt, sollten wir eventuell noch die nötige Breite für die Labels feststellen:
Code: Alles auswählen
maxlen = 0
for key in keys:
maxlen = max(maxlen,len(key))
print(maxlen)
Re: Dynamische Generierung von Eingabemasken
Verfasst: Montag 26. Juni 2017, 21:33
von __deets__
Wozu ein dict, wenn du eh eine Ordnung brauchst? Da reicht doch die Liste völlig. Und was soll diese extra Schleife mit "get_dictionary"?
So oder so halte ich diesen Ansatz für ziemlich sinnlos. So ein Vorgehen hat wert wenn man zB mit SQLAlchemy-Objekten arbeitet, weil man da schon viele Metadaten hat, die man nutzen kann. Letztlich aber sind auch im Web zB bei Django Admin oder rails scaffolding die Einsatzmöglichkeiten beschränkt. Aber das hat dich ja noch nie abgehalten

Re: Dynamische Generierung von Eingabemasken
Verfasst: Montag 26. Juni 2017, 22:34
von Alfons Mittelmeyer
__deets__ hat geschrieben:Wozu ein dict, wenn du eh eine Ordnung brauchst? Da reicht doch die Liste völlig. Und was soll diese extra Schleife mit "get_dictionary"?
Wofür man das Dictionary braucht, ganz einfach, man will ja nicht nur die Inhalte darstellen, sondern auch abspeichern. Zu get_dictionary kommen wir später.
Zum Darstellen braucht man mal kein dictionary.
Das wäre mal die Eingabemaske. Für gewisse Felder kann man eine Sonderbehandlung machen, etwa dass die PLZ nur 5 Stellen hat, oder dass man sie abprüft, oder dass man für manche Felder besser eine Spinbox verwendet.
Code: Alles auswählen
# -*- coding: utf-8 -*-
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class Input_Class:
def __init__(self,get_dictionary=None):
if get_dictionary:
self.get_dictionary = get_dictionary
else:
self.dictionary = {
'Name': '',
'Vorname': '',
'Straße': '',
'Hausnummer':'',
'PLZ':'',
'Ort':'',
}
self.get_dictionary = self.get_own_dictionary
def get_own_dictionary(self):
return self.dictionary
def keys(self):
return [ 'Name',
'Vorname',
'Straße',
'Hausnummer',
'PLZ',
'Ort',
]
def __getitem__(self,key):
return self.get_dictionary()[key]
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
# widget definitions ===================================
self.Eingabemaske = Eingabemaske(self)
self.Eingabemaske.pack(fill='x')
self.Eingabemaske.create_Eingabemaske(Input_Class())
class Eingabemaske(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
self.config(text='Eingabemaske')
# widget definitions ===================================
self.content = tk.Frame(self)
self.content.pack(fill='x')
def create_Eingabemaske(self,input_object):
keys = input_object.keys()
maxlen = 0
for key in keys:
maxlen = max(maxlen,len(key))
self.content.destroy()
self.content = tk.Frame(self)
self.content.pack(fill='x')
for key in keys:
frame = tk.Frame(self.content)
frame.pack(fill='x')
label = tk.Label(frame,text = key, width = maxlen+1,anchor = 'e')
label.pack(side = 'left')
# Sonderbehandlung für spezielle Eingabefelder
if key == 'PLZ':
width = 5
expand = 0
fill = None
elif key == 'Hausnummer':
width = 6
expand = 0
fill = None
else:
width = 30
expand = 1
fill = 'x'
# ===========================================
entry = tk.Entry(frame,width = width)
entry.delete(0,'end')
entry.insert(0,str(input_object[key]))
entry.pack(side = 'left',fill = fill,expand= expand,padx = 5,pady=1)
if __name__ == '__main__':
Application().mainloop()
Das ist ein einfaches Pack Layout. Man kann aber jedes beliebige Layout nehmen.
Wofür wir das Dictionary brauchen? Zum Speichern
Verfasst: Montag 26. Juni 2017, 23:23
von Alfons Mittelmeyer
Da gibt es zwei Möglichkeiten:
a) jeden Eintrag mit Enter bestätigen und damit speichern
b) Die Maske ausfüllen und am Ende einen Button zum Übernehmen drücken
Das ist die Methode b):
Code: Alles auswählen
# -*- coding: utf-8 -*-
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class Input_Class:
def __init__(self,get_dictionary=None,set_dictionary = None):
if get_dictionary:
self.get_dictionary = get_dictionary
else:
self.dictionary = {
'Name': '',
'Vorname': '',
'Straße': '',
'Hausnummer':'',
'PLZ':'',
'Ort':'',
}
self.get_dictionary = self.get_own_dictionary
if set_dictionary:
self.set_dictionary = set_dictionary
else:
self.set_dictionary = self.set_own_dictionary
def get_own_dictionary(self):
return self.dictionary
def set_own_dictionary(self,**kwargs):
for key in kwargs:
self.dictionary[key] = kwargs[key]
def config(self,**kwargs):
if kwargs:
self.set_dictionary(**kwargs)
return self.get_dictionary()
def __getitem__(self,key):
return self.config()[key]
def __setitem__(self,key,value):
self.config(**{key : value})
def keys(self):
return [ 'Name',
'Vorname',
'Straße',
'Hausnummer',
'PLZ',
'Ort',
]
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
# widget definitions ===================================
self.Eingabemaske = Eingabemaske(self)
self.Eingabemaske.pack(fill='x')
self.Eingabemaske.create_Eingabemaske(Input_Class())
class Eingabemaske(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
self.config(text='Eingabemaske')
# widget definitions ===================================
self.content = tk.Frame(self)
self.content.pack(fill='x')
def create_Eingabemaske(self,input_object):
keys = input_object.keys()
maxlen = 0
for key in keys:
maxlen = max(maxlen,len(key))
self.content.destroy()
self.content = tk.Frame(self)
self.content.pack(fill='x')
entrylist = [] # Liste mit den Eingabefeldern zum Speichern
for key in keys:
frame = tk.Frame(self.content)
frame.pack(fill='x')
label = tk.Label(frame,text = key, width = maxlen+1,anchor = 'e')
label.pack(side = 'left')
# Sonderbehandlung für spezielle Eingabefelder
if key == 'PLZ':
width = 5
expand = 0
fill = None
elif key == 'Hausnummer':
width = 6
expand = 0
fill = None
else:
width = 30
expand = 1
fill = 'x'
# ===========================================
entry = tk.Entry(frame,width = width)
entry.key = key # das ist zum Speichern
entrylist.append(entry) # und das auch
entry.delete(0,'end')
entry.insert(0,str(input_object[key]))
entry.pack(side = 'left',fill = fill,expand= expand,padx = 5,pady=1)
def save_input():
for entry in entrylist:
input_object[entry.key] = str(entry.get())
# Zum Anschauen =============================
print(input_object.config())
okbutton = tk.Button(self.content,text = 'OK')
okbutton.pack(anchor = 'e')
okbutton['command'] = save_input
if __name__ == '__main__':
Application().mainloop()
Re: Vielleicht noch das zuvor
Verfasst: Dienstag 27. Juni 2017, 00:20
von snafu
Alfons Mittelmeyer hat geschrieben:Abhängig vom gewählten Layout und wenn es auf den Platz ankommt, sollten wir eventuell noch die nötige Breite für die Labels feststellen:
Code: Alles auswählen
maxlen = 0
for key in keys:
maxlen = max(maxlen,len(key))
print(maxlen)
Das geht auch kürzer:
Das wäre dann fast das komplette Beispiel
Verfasst: Dienstag 27. Juni 2017, 07:38
von Alfons Mittelmeyer
Die Klasse wurde reduziert und erweitert, auf das, was man in diesem Falle braucht. Außerdem wurde noch eine Fehlerbehandlung eingebaut:
Code: Alles auswählen
# -*- coding: utf-8 -*-
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
import re
class Input_Class:
def __init__(self, save_dictionary=None, dictionary = None):
self.dictionary = dictionary if dictionary else { key : '' for key in self.keys() }
self.save_dictionary = save_dictionary
def save(self):
for key in self.keys():
if not len(self.dictionary[key].strip()):
return False,key + ' fehlt'
plz = self.dictionary['PLZ']
if not re.match('(?:[0-9]{5})',plz):
return False,'PLZ stimmt nicht'
if self.save_dictionary:
self.save_dictionary(**self.dictionary)
else:
print(self.dictionary)
print('\nsave function missing')
return True,''
def keys(self):
return [ 'Name',
'Vorname',
'Straße',
'Hausnummer',
'PLZ',
'Ort',
]
def __getitem__(self,key):
return self.dictionary[key]
def __setitem__(self,key,value):
self.dictionary[key] = value
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
# widget definitions ===================================
self.Eingabemaske = Eingabemaske(self)
self.Eingabemaske.pack(fill='x')
self.Eingabemaske.create_Eingabemaske(Input_Class())
class Eingabemaske(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
self.config(text='Eingabemaske')
# widget definitions ===================================
self.content = tk.Frame(self)
self.content.pack(fill='x')
def create_Eingabemaske(self,input_object):
keys = input_object.keys()
maxlen = max(map(len, keys))
self.content.destroy()
self.content = tk.Frame(self)
self.content.pack(fill='x')
entrylist = [] # Liste mit den Eingabefeldern zum Speichern
for key in keys:
frame = tk.Frame(self.content)
frame.pack(fill='x')
label = tk.Label(frame,text = key, width = maxlen+1,anchor = 'e')
label.pack(side = 'left')
# Sonderbehandlung für spezielle Eingabefelder
if key == 'PLZ':
width = 5
expand = 0
fill = None
elif key == 'Hausnummer':
width = 6
expand = 0
fill = None
else:
width = 30
expand = 1
fill = 'x'
# ===========================================
entry = tk.Entry(frame,width = width)
entry.key = key # das ist zum Speichern
entrylist.append(entry) # und das auch
entry.delete(0,'end')
entry.insert(0,str(input_object[key]))
entry.pack(side = 'left',fill = fill,expand= expand,padx = 5,pady=1)
status_label = tk.Label(self.content)
status_label.pack(side = 'left')
def save_input():
for entry in entrylist:
input_object[entry.key] = str(entry.get())
result,status = input_object.save()
status_label.config(text = status,fg='blue',font = 'TkDefaultFont 10 bold')
# positive result should be reported
okbutton = tk.Button(self.content,text = 'OK')
okbutton.pack(side = 'right', anchor = 'e')
okbutton['command'] = save_input
if __name__ == '__main__':
Application().mainloop()
Re: Dynamische Generierung von Eingabemasken
Verfasst: Dienstag 27. Juni 2017, 08:23
von Sirius3
@Alfons Mittelmeyer: die Klasse Input_Class ist aus vielerlei Gründen schlecht. Zuerst der Name. Dass es eine Klasse ist, sieht man an der Schreibweise; es handelt sich nicht nur um Input sondern auch um Output. Die Felder sind fest verdrahtet und dazu noch mehrfach im Code. Wenn ich eine andere get_dictionary oder set_dictionary-Methode haben will, schreibe ich eine eigene Klasse und übergebe keine Funktionen an eine generische Klasse. Damit sieht die Input_Class so aus:
Code: Alles auswählen
class Address(object):
KEYS = [
'Name',
'Vorname',
'Straße',
'Hausnummer',
'PLZ',
'Ort',
]
def __init__(self):
self.dictionary = dict.fromkeys(self.KEYS, "")
def get_dictionary(self):
return self.dictionary
def set_dictionary(self,**kwargs):
self.dictionary.update(kwargs)
def config(self,**kwargs):
self.dictionary.update(**kwargs)
return self.dictionary
def __getitem__(self, key):
return self.dictionary[key]
def __setitem__(self, key, value):
self.dictionary[key] = value
def keys(self):
return list(self.KEYS)
Jetzt hat diese Klasse zwei Aufgaben, die nichts miteinander zu tun haben: 1. das festlegen der Schlüssel, die nicht als Konstante in einer Klasse, sondern als Konfigurationsparameter übergeben werden sollte und 2. das Speichern der Eingaben, was auch durch ein einfaches Wörterbuch möglich wäre. Die Klasse wird also ersetzt durch Wörterbuch und Liste
Code: Alles auswählen
def create_Eingabemaske(self, keys): [...]
def save_input():
output = {}
for key, entry in zip(keys, entrylist):
output[key] = entry.get()
print(output)
Re: Dynamische Generierung von Eingabemasken
Verfasst: Dienstag 27. Juni 2017, 09:25
von Alfons Mittelmeyer
Sirius3: wenn man allerdings davon ausgeht, dass man die wichtigsten Dictionary Einträge kennt, aber nicht alle, dann ist keys zu ergänzen:
Code: Alles auswählen
def keys(self):
keys = list(self.KEYS)
dictionary = dict(self.get_dictionary())
for key in KEYS:
dictionary.pop(key,None)
for key in dictionary:
keys.append(key)
return keys
Re: Dynamische Generierung von Eingabemasken
Verfasst: Dienstag 27. Juni 2017, 09:43
von Alfons Mittelmeyer
Wir sollten auch noch davon ausgehen, dass manche Dictionaries nicht alle keys haben:
Code: Alles auswählen
def keys(self):
keys = []
dictionary = dict(self.get_dictionary())
for key in KEYS:
if key in dictionary:
keys.append(key)
dictionary.pop(key,None)
for key in dictionary:
keys.append(key)
Re: Dynamische Generierung von Eingabemasken
Verfasst: Dienstag 27. Juni 2017, 09:52
von Alfons Mittelmeyer
Wovon wir noch ausgehen sollten. Das Dictionary könnte auch mehrsprachig sein. Wenn wir auf eine Dictionary Kopie mit key zugreifen, könnten wir eine Liste mit Einträgen in allerlei Sprachen bekommen. Eindeutig wird es nur, wenn wir auf das Original Dictionary zugreifen, weil das dann den Eintrag in der aktuellen Sprache liefert:
Code: Alles auswählen
def __init__(self,extern_dictionary):
self.extern_dictionary = extern_dictionary
def get_dictionary(self):
dictionary = {}
for key in self.extern_dictionary.config():
dictionary[key] = self.extern_dictionary[key]
return dictionary
Re: Dynamische Generierung von Eingabemasken
Verfasst: Dienstag 27. Juni 2017, 10:02
von Alfons Mittelmeyer
Und so sieht es doch schon gut aus:
Code: Alles auswählen
class DictionaryAdvanced:
KEYS = [
'Name',
'Vorname',
'Straße',
'Hausnummer',
'PLZ',
'Ort',
]
def __init__(self,extern_dictionary):
self.extern_dictionary = extern_dictionary
def get_dictionary(self):
dictionary = {}
for key in self.extern_dictionary.config():
dictionary[key] = self.extern_dictionary[key]
return dictionary
def config(self,**kwargs):
if kwargs:
self.extern_dictionary.config(**kwargs)
return self.get_dictionary()
def __getitem__(self,key):
return self.config()[key]
def __setitem__(self,key,value):
self.config(**{key : value})
def keys(self):
keys = []
dictionary = dict(self.get_dictionary())
for key in KEYS:
if key in dictionary:
keys.append(key)
dictionary.pop(key,None)
for key in dictionary:
keys.append(key)
return keys
Re: Dynamische Generierung von Eingabemasken
Verfasst: Dienstag 27. Juni 2017, 10:05
von Alfons Mittelmeyer
Naja, das auch noch:
Code: Alles auswählen
def __setitem__(self,key,value):
try:
self.config(**{key : value})
except: ValueError
pass
Re: Dynamische Generierung von Eingabemasken
Verfasst: Dienstag 27. Juni 2017, 10:36
von Sirius3
@Alfons Mittelmeyer: Du hast es noch nicht ganz erfasst: Deine Wörterbuchklasse ist ganz und gar überflüssig. Definition der Formularelemente und Inhalt sind zwei verschiedene Dinge und gehören nicht in einer Klasse gemischt. Die Definition kannst Du noch um mehrere Sprachen, Anzeigeoptionen und Validierung erweitern, trotzdem ist das kein Wörterbuch und erst recht keins, wofür eine eigene Klasse nötig wäre.