import json import pandas as pd import os class DataModel: def __init__(self): self._observers = {} self._counter = 0 # self._data_controller = DataController() # Externer hypothetischer Datencontroller # self._data_controller.subscribe(self) def subscribe(self, observer): self._counter += 1 self._observers[self._counter] = observer return self._counter def unsubscribe(self, observer_id): self._observers.pop(observer_id) def notify(self, data): for observer in self._observers.values(): observer.notify(data) class CadItem(DataModel): """ This item contains all data for writing all necessary data to the solid edg cad file """ # diese Daten bilden dann die Impfdaten data_keys = [ "Author", "Teilenummer", "StartRevision", "Bezeichnung1", "Bezeichnung2", "Bezeichnung4", "KategorieNE", "BeschaffungsartNE", "TOS-Gruppe_ERP", "Dispogruppe", "Dispolaufgruppe", "WerkstofftypNE", "WerkstoffNE", "Oberflaechenbehandlung", "Farbe", "KalkulationsartNE", "RuestcodeAusw", "Fertigungsart", "Allgemeintoleranz", "HalbzeugInternAngabe", "Halbzeug", "HalbzeugOhneSaegeliste", "EinheitNE", "FOS-GruppeNE", "Hersteller", "HerstellerTeilenummer", "Serien-Status", "Kantennorm", "Oberflaechennorm", "Massnorm", "Tolerierungsnorm", "TOS-Gruppe", "TOS_Schoenenberger_Produkt", "TOS_Automation", "TOS_Maschinenelement", "TOS_Schoenenberger_Komponenten", "TOS_Pneumatik", "TOS_Konfig", "TOS_ILS", "TOS_MAS", "TOS_Spinnereikomponente", "TOS_Betriebsmittel", "TOS_Geruest", "TOS_FremdTransport", "TOS_MAS_Konfig", "TOS_Schaltschrank", "TOS_Schalt_Einbau", "TOS_Dezentral", "TOS_Automation_Sensorik", "TOS_Kabel", "TOS_Installation", "TOS_Automation_Sonstiges", "TOS_Verbindungselement", "TOS_Lager", "TOS_Kraft_Drehmoment", "TOS_Sicherungselement", "TOS_Bedienungselement", "TOS_ILS_2", "TOS_ILS_Foerderer", "TOS_MAS_Fahrstecke", "TOS_Trolley", "TOS_Trolley_Projekte", "TOS_Trolley_Omniflo", "TOS_Trolley_Spinnerei", "TOS_Trolley_ILS", "Änderungsbeschreibung", "Freigabevermerk", "ZusaetzlicheInformationen"] gui_data_keys = [ "asm_id", "teilenummer", "datenbank", "pdm_kategorie_neu", "neuaufbau", "aus_halbzeug_neu", "halbzeugnummer_neu", "halbzeuglaenge_neu", "halbzeugoberflaeche_neu", "halbzeugfarbe_neu", "lebenszyklus_status_neu", "model3d_neu", "bezeichnung1_sivas", "bezeichnung1_neu", "bezeichnung2_sivas", "bezeichnung2_neu", "halbzeugOhneSaege_sivas", "halbzeugOhneSaege_neu", "ruestcode_sivas", "ruestcode_neu", "fertigungsart_sivas", "fertigungsart_neu", "allgemeintoleranz_sivas", "allgemeintoleranz_neu", "fosGruppe_sivas", "fosGruppe_neu", "kalkulationsart_sivas", "kalkulationsart_neu", "beschaffungsart_sivas", "beschaffungsart_neu", "mengeneinheit_sivas", "mengeneinheit_neu", "halbzeug_sivas", "halbzeug_neu", "tosgruppe_sivas", "tosgruppe_neu", "dispogruppe_sivas", "dispogruppe_neu", "dispolaufgruppe_sivas","dispolaufgruppe_neu", "hersteller_sivas", "hersteller_neu", "ersatzfuer_sivas", "ersatzfuer_neu", "ersetztdurch_sivas", "ersetztdurch_neu", "herstteilenr_sivas", "herstteilenr_neu", "werkstoffdiskr_sivas", "werkstofftyp_sivas", "werkstofftyp_neu", "material_sivas", "material_neu", "oberflaeche_neu", "farbe_neu", "version_sivas", "version_neu", "aenderungsindex_sivas", "aenderungsindex_neu", "aenderungstext_sivas", "aenderungstext_neu", "freigabevermerk_sivas", "freigabevermerk_neu", "zusatzinfos_auto_text", "zusatzinfos_bendef_text", # Felder der Comboboxen. benannt wie deren callbacks "cb_pdm_kategorie_neu", "cb_halbzeug_neu", "cb_halbzeugoberflaeche", "cb_halbzeugfarbe", "cb_lebenszyklus_status_neu", "cb_3Dmodel_neu", "cb_halbzeugOhneSaege_neu", "cb_ruestcode_neu", "cb_fertigungsart_neu", "cb_allgemeintoleranz_neu", "cb_fosGruppe_neu", "cb_kalkulationsart_neu", "cb_beschaffungsart_neu", "cb_mengeneinheit_neu", "cb_dispogruppe_neu", "cb_dispolaufgruppe_neu", "cb_hersteller_neu", "cb_werkstofftyp_neu", "cb_material_neu", "cb_oberflaeche_neu", "cb_farbe_neu", # buttons "cb_suche_asm", "cb_speichern", "cb_migrieren", "cb_zurücksetzen", ] # dies sind die Excel Headel der SIVAS csv Export Datei # und wie diese in das Datenmodell der Gui integriert werden kann excel_to_gui = { "Teilenummer":"teilenummer", "Bezeichnung1":"bezeichnung1_sivas", "Bezeichnung2":"bezeichnung2_sivas", "Beschaffungsart":"beschaffungsart_sivas", "Mengeneinheit":"mengeneinheit_sivas", "Halbzeug":"halbzeug_sivas", "TOS_Gruppe":"tosgruppe_sivas", "Dispogruppe":"dispolaufgruppe_sivas", "Dispolaufgruppe":"dispolaufgruppe_sivas", "ErsatzFuer":"ersatzfuer_neu", "ErsetztDurch":"ersetztdurch_neu", "AktuellerIndex":"aenderungsindex_sivas", "Hersteller":"hersteller_sivas", "HerstellerTeilenummer":"herstteilenr_sivas", "Version":"version_sivas", "HalbzeugExtern":"halbzeug_sivas", "Werkstoff":"werkstofftyp_sivas", "Oberfläche":"cb_oberflaeche_neu", # "Truemmer":"truemmer", # "HzOhneSaegeliste":"", "Ruestcode":"ruestcode_sivas", "Fertigungsart":"fertigungsart_sivas", "FosGruppe":"fosGruppe_sivas", "Kalkulationsart":"kalkulationsart_sivas", #"Indexerfasser":"", "Aenderungstext":"aenderungstext_sivas", "Freigabevermerk":"freigabevermerk_sivas", # "Indexbearbeiter":"in" } def __init__(self): """ is initalized with its unique id""" super().__init__() self._red_ids = {} self._parent_children_mapping = {} self._data = {} self._gui_data = {} self._read_only_items = {} self._controller = None self._logic = None def add_logic(self, logic): self._logic = logic def set_controller(self, controller): self._controller = controller def set_asm_id(self, asm_id): self.set_gui_data("asm_id", asm_id) def get_asm_id(self): return self.get_gui_data("asm_id") def get_current_part_id(self): return self.get_gui_data("teilenummer") def set_parent_children(self, parent_children_mapping): """ contains all id relations below, data of subassemblies etc. in a dict of the kind parent-children """ self._parent_children_mapping = parent_children_mapping def get_parent_children(self): return self._parent_children_mapping def set_red_ids(self, red_ids): """ these ids are not yet known by the PDM""" self._red_ids = red_ids def get_red_ids(self): return self._red_ids # Methoden um die Verwendbarkeit einzelner Schalter auszugrauen def set_read_only_dict(self, data:dict): for k,v in data: self.set_read_only(k,v) def set_read_only(self, key, val): if key not in self._gui_data: raise Exception("this data can not be set "+ key) else: self._read_only_items[key] = val def get_read_only(self, key): return self._read_only_items[key] def get_all_read_only_data(self): return self._read_only_items # Daten zum Impfen merken def set_data_dict(self, data:dict): for k,v in data: self.set_data(k,v) def set_data(self, key, val): if key not in self._data_keys: raise Exception("this data can not be set "+ key) else: self._data[key] = val def get_data(self, key): """ gibt ein Datenstück zurück """ return self._data[key] def get_all_data(self): """ gibt alle enthaltenen Daten zurück """ return self._data # Daten die in der GUI gespeichert werden sollen def set_gui_dict(self, data:dict): """ setzt die Daten der GUI """ for k,v in data.items(): self.set_gui_data(k,v) def set_gui_data(self, key, val): """ merkt sich ein Datenatom für die GUI """ if key not in self.gui_data_keys: raise Exception("this data can not be set "+ key) else: self._gui_data[key] = val def get_gui_data(self, key): if key in self._gui_data: return self._gui_data[key] else: return None def get_all_gui_data(self): return self._gui_data def csv2guidata(self, data): translated_data = dict() for k,v in data.items(): if k in self.excel_to_gui and v is not None: translated_data[self.excel_to_gui[k]] = v # Spezial: Befüllung von Änderungstext mit dem Author, falls in der .csv vorhanden if "Indexerfasser" in data and "Aenderungstext" in data: translated_data["aenderungstext_sivas"] = '{aenderungstext} (von {author})'.format(aenderungstext=data["Aenderungstext"], author=data["Indexerfasser"]) # Indexerfasser wird nicht in der gui verwaltet. Deshalb Modifikation aus den Rohdaten self.set_gui_dict(translated_data) return translated_data def sivas_data_from_csv(self, cid): path = os.path.join(self._controller.get_env("data"), cid + '.csv') if os.path.exists(path): data = self._load_csv(path) return data return None def _load_csv(self, path): """lädt die SIVAS csv Datei in die Felder für die Oberfläche """ if not os.path.exists(path): return None df = pd.read_csv(path, sep=';') ret = dict() # baue aus der gegebenen Zeile ein dict d = df.to_dict() for k,v in d.items(): value = v[0] # schmeisse alle NaN raus if pd.isna(value): value = None ret[k] = value return ret def from_json_file(self, subpath, cid): path = os.path.join(subpath, cid + '.json') if os.path.exists(path): self.load(path) return False def from_json(self, json_str): jsonobj = json.loads(json_str) if "gui_data" in jsonobj: gui_data = jsonobj["gui_data"] self.set_gui_dict(gui_data) else: raise Exception("no gui_data given in string") if "parent_children_mapping" in jsonobj: parent_children_mapping = jsonobj["parent_children_mapping"] self.set_parent_children(parent_children_mapping) else: raise Exception("no parent_children_mapping given in string") if "red_ids" in jsonobj: red_ids = jsonobj["red_ids"] self.set_red_ids(red_ids) return True def to_dict(self, tree=False ): jsonobj = dict() # die Oberflächendaten gui_data = self.get_all_gui_data() jsonobj["gui_data"] = gui_data # der Baum if tree: parent_children_mapping = self.get_parent_children() jsonobj["parent_children_mapping"] = parent_children_mapping # die ids der nicht migrierten Dateien red_ids = self.get_red_ids() jsonobj["red_ids"] = red_ids return jsonobj def to_json(self, tree=False): obj = self.to_dict(tree) return json.dumps(obj) def load(self, path): """loads all data of a model from a json string""" try: with open(path, 'r') as f: self.from_json(json.load(f)) except Exception: raise Exception("guid_data, data, parent_children_mapping or red_ids not found") def save(self, path, tree=False): """saves all data of model to a json string""" with open(path, 'w') as f: json.dump(self.to_dict(tree), f) def callback(self, key, value): if self._logic == None: raise Exception("no logic set") else: self._logic.callback(key, value) def get_dependent(self, key): if self._logic == None: raise Exception("no logic set") else: self._logic.get_dependent(key) def set_gui_defaults(self): self._logic.set_gui_defaults() class CadItemRepository: """ container class for all CadItems in the local folder also just managed by the controller """ def __init__(self): self.caditems = [] def add(self, caditem): self.caditems.append(caditem) def get(self, id): for caditem in self.caditems: if caditem.id == id: return caditem return None def get_all(self): return self.caditems def update(self, old_item, new_item): self.delete(old_item.id) self.add(new_item) def delete(self, id): for p in self.caditems: if p.id == id: self.caditems.remove(p) return raise Exception("CadItem not found") class GuiLogic(): """ Class for business logic. implementing the dependencies between different user inputs """ def __init__(self, model, configs): # das Modell soll hier nur verwendet werden um aktuell Zustände abzufragen! # alles weitere zum Setzen von Daten etc. muss über den Controller laufen, also zurück gegeben werden. self.model = model # hier holt man die Daten der Configs self.config = configs # hier sind alle Callbacks bzw. deren Comboboxen def set_gui_defaults(self): # set defaults from given logic self.call_and_set_data('cb_pdm_kategorie_neu') self.call_and_set_data('cb_neuaufbau') self.call_and_set_data('cb_aus_halbzeug_neu') self.call_and_set_data('cb_halbzeugoberflaeche') def call_and_set_data(self, callbackfunc): eval('self.model.set_gui_dict(self.'+callbackfunc+'(None))') def callback(self, key, value): """gibt ein dict zurück, welches neu im Modell gesetzt wird""" ret = dict() if key == 'cb_pdm_kategorie_neu': ret = self.cb_pdm_kategorie_neu(value) elif key == 'cb_neuaufbau': ret = self.cb_neuaufbau(value) elif key == 'cb_aus_halbzeug_neu': ret = self.cb_aus_halbzeug_neu(value) elif key == "cb_halbzeugoberflaeche": ret = self.cb_halbzeugoberflaeche(value) elif key == "cb_halbzeugfarbe": ret = self.cb_halbzeugfarbe(value) elif key == 'cb_lebenszyklus_status_neu': ret = self.cb_lebenszyklus_status_neu(value) elif key == 'cb_3Dmodel_neu': ret = self.cb_3Dmodel_neu(value) elif key == 'cb_halbzeugOhneSaege_neu': pass elif key == 'cb_ruestcode_neu': pass elif key == 'cb_fertigungsart_neu': pass elif key == 'cb_allgemeintoleranz_neu': pass elif key == 'cb_fosGruppe_neu': pass elif key == 'cb_kalkulationsart_neu': pass elif key == 'cb_beschaffungsart_neu': pass elif key == 'cb_mengeneinheit_neu': pass elif key == 'cb_halbzeug_neu': pass elif key == 'cb_dispogruppe_neu': pass elif key == 'cb_dispolaufgruppe_neu': pass elif key == 'cb_hersteller_neu': pass elif key == 'cb_werkstoffdiskrepanz': pass elif key == 'cb_werkstofftyp_neu': pass # ret = self.cb_werkstofftyp_neu(value) elif key == 'cb_material_neu': pass elif key == 'cb_oberflaeche_neu': pass elif key == 'cb_farbe_neu': ret = self.cb_farbe_neu(value) elif key == 'cb_speichern': pass elif key == 'cb_migrieren': pass elif key == 'cb_zurücksetzen': pass elif key == 'cb_suche_asm': pass else: raise Exception("this callback does not exist "+key) return ret def get_dependent(self, key): """gibt die Namen der Callbacks zurück, welche nach dem Aufruf der ursprünglichen Methode wegen der Abhängigkeiten der Comboboxen anschliessend folgen sollen""" if key == 'cb_pdm_kategorie_neu': ret = ['cb_neuaufbau', 'cb_aus_halbzeug_neu'] elif key == 'cb_neuaufbau': ret = [] elif key == 'cb_aus_halbzeug_neu': ret = [] elif key == "cb_halbzeugoberflaeche": ret = [] elif key == "cb_halbzeugfarbe": ret = [] elif key == 'cb_lebenszyklus_status_neu': ret = [] elif key == 'cb_3Dmodel_neu': ret = [] elif key == 'cb_halbzeugOhneSaege_neu': ret = [] elif key == 'cb_ruestcode_neu': ret = [] elif key == 'cb_fertigungsart_neu': ret = [] elif key == 'cb_allgemeintoleranz_neu': ret = [] elif key == 'cb_fosGruppe_neu': ret = [] elif key == 'cb_kalkulationsart_neu': ret = [] elif key == 'cb_beschaffungsart_neu': ret = [] elif key == 'cb_mengeneinheit_neu': ret = [] elif key == 'cb_halbzeug_neu': ret = [] elif key == 'cb_dispogruppe_neu': ret = [] elif key == 'cb_dispolaufgruppe_neu': ret = [] elif key == 'cb_hersteller_neu': ret = [] elif key == 'cb_werkstoffdiskrepanz': ret = [] elif key == 'cb_werkstofftyp_neu': ret = [] elif key == 'cb_material_neu': ret = [] elif key == 'cb_oberflaeche_neu': ret = [] elif key == 'cb_farbe_neu': ret = [] elif key == 'cb_speichern': ret = [] elif key == 'cb_migrieren': ret = [] elif key == 'cb_zurücksetzen': ret = [] elif key == 'cb_suche_asm': ret = [] else: raise Exception("this callback does not exist "+key) return ret def cb_pdm_kategorie_neu(self, selected): """setzt die Dropdownliste mit , Baugruppe, Einzelteil, Kaufteil, Schweissbaugruppe """ ret = dict() categories = self.config.Allgemein.get_options("Kategorien") if selected is None: ret['pdm_kategorie_neu'] = categories[0] ret['cb_pdm_kategorie_neu'] = categories else: ret['pdm_kategorie_neu'] = selected return ret def cb_neuaufbau(self, trueOrfalse): ret = dict() pdm_kat = self.model.get_gui_data("pdm_kategorie_neu") if pdm_kat != "Einzelteil" or pdm_kat != "Kaufteil": ret["neuaufbau"] = False return ret def cb_aus_halbzeug_neu(self, trueOrfalse): ret = dict() pdm_kat = self.model.get_gui_data("pdm_kategorie_neu") if pdm_kat == "Einzelteil": pass else: ret["aus_halbzeug_neu"] = False return ret def cb_halbzeugoberflaeche(self, selected): ret = dict() aus_halbzeug = self.model.get_gui_data("aus_halbzeug_neu") if aus_halbzeug == "True": oarten = self.config.Oberfläche.get_oberflächen_behandlungen() if selected is None: ret['halbzeugoberflaeche_neu'] = oarten[0] ret['cb_halbzeugoberflaeche'] = oarten else: ret['halbzeugoberflaeche_neu'] = selected else: ret = { 'halbzeugoberflaeche_neu': "", 'cb_halbzeugoberflaeche': "", } return ret def cb_lebenszyklus_status_neu(self, selected): ret = dict() lstatus = self.config.Allgemein.get_options("Lebenszyklus") # Serie, Prototyp if selected is None: ret['lebenszyklus_status_neu'] = lstatus[0] ret['cb_lebenszyklus_status_neu'] = lstatus else: ret['cb_lebenszyklus_status_neu'] = selected return ret def cb_halbzeugfarbe(self, selected): ret = dict() halbzeugoberflaeche = self.model.get_gui_data("halbzeugoberflaeche_neu") aus_halbzeug = self.model.get_gui_data("aus_halbzeug_neu") # setze die Inhalte der abhängigen Comboboxen neu ret = { 'halbzeugfarbe_neu': '', 'cb_halbzeugfarbe': '', } if aus_halbzeug == "True": if halbzeugoberflaeche == "eloxieren": farben_elox = self.config.Farben.get_farben_eloxieren() if selected is None: ret['halbzeugfarbe_neu'] = farben_elox[0] # Default, falls nichts gewählt ist ret['cb_halbzeugfarbe'] = farben_elox # Liste in der Combobox else: ret['halbzeugfarbe_neu'] = selected # vom Nutzer ausgewählter Wert elif halbzeugoberflaeche == "lackieren" or halbzeugoberflaeche == "pulverbeschichten": farbauswahl = self.config.Farben.get_farbauswahl() if selected is None: ret['halbzeugfarbe_neu'] = farbauswahl[0] ret['cb_halbzeugfarbe'] = farbauswahl else: ret['halbzeugfarbe_neu'] = selected else: pass return ret def cb_3Dmodel_neu(self, selected): ret = dict() pdm_kategorie_neu = self.model.get_gui_data("pdm_kategorie_neu") if pdm_kategorie_neu == "Baugruppe" or pdm_kategorie_neu == "Schweissbaugruppe": # Defaultwert = \\ssg.local\freigaben\Abteilungen\Entwicklung\CAD\Standards\SolidEdge\Template\DIN Metric\baugruppe.asm # Dropdownwerte = keine # state_ComboBox = disabled # state_Button = disabled # ret = { # '': '', # '': '', # } pass elif pdm_kategorie_neu == "Kaufteil": # Defaultwert = \\ssg.local\freigaben\SIVAS_CAD_EDM\Migration\06_3D_Vorlagen\ET_mit_Volumen.par # Dropdownwerte = keine # state_ComboBox = disabled # state_Button = disabled pass elif pdm_kategorie_neu == "Einzelteil": aus_halbzeug = self.model.get_gui_data("aus_halbzeug_neu") neuaufbau = self.model.get_gui_data("neuaufbau") if aus_halbzeug == "True" or neuaufbau == "True": # Defaultwert = \\ssg.local\freigaben\SIVAS_CAD_EDM\Migration\06_3D_Vorlagen\ET_mit_Volumen.par # Dropdownwerte = keine # state_ComboBox = disabled # state_Button = disabled pass else: # Defaultwert = "" # Dropdownwerte = Dateipfade von allen .par-Dateien, die die aktuelle Teilenummer im Dateinamen aufweisen und sich gleichzeitig in einem der rekursiv durchsuchten Pfade aus der Sektion "3D-Modelle" in "Zielpfade.cfg" befinden. # state_ComboBox = readonly # state_Button = keiner # IF Button "Durchsuchen" geklickt und benutzerdefinierte Solid Edge-Datei gewählt: # Defaultwert = Dateipfad der gewählten Solid Edge-Datei pass return ret # def cb_werkstofftyp_neu(self, selected_werkstoff): # """bekommt Aluminium, Stahl etc. und setzt dann die anderen Felder der Oberfläche""" # # Logik, die steuert, welcher Defaultwert gilt: # # In den nachfolgenden Fällen darf kein Defaultwert eingetragen # # werden (selbst wenn in from_siv.csv ein Wert in der Spalte # # "Werkstoff" eingetragen sein sollte): # # PDM-Kategorie == "Baugruppe" # # PDM-Kategorie == "Schweissbaugruppe" # # PDM-Kategorie == "Einzelteil" und Aus Halbzeug == True (Haken gesetzt) # # Gilt PDM-Kategorie == "Kaufteil" soll der Defaultwert "siehe # # Hersteller" eingetragen werden # # Gilt PDM-Kategorie == "Einzelteil" und Aus Halbzeug == False (kein # # Haken), dann wird der Defaultwert wie folgt bestimmt: # ret = dict() # # das Feld selbst mit dem Selektierten beschreiben # ret['werkstofftyp_neu']= selected_werkstoff # pdm_kat = self.model.get_gui_data("pdm_kategorie_neu") # aus_halbzeug = self.model.get_gui_data("aus_halbzeug_neu") # if pdm_kat == 'Einzelteil' and aus_halbzeug is False: # wnamen = self.config.Werkstoffe.get_werkstoffe_of_name(selected_werkstoff) # # setze die Inhalte der abhängigen Comboboxen neu und den Wert im Modell # ret = { # # das Feld selbst mit dem Selektierten beschreiben # 'werkstofftyp_neu': selected_werkstoff, # # die neuen Inhalte der comboboxen setzen # 'cb_material_neu': wnamen, # # der angezeigte Wert der Combos sollte anfangs dem ersten der Liste entsprechen # 'material_neu': wnamen[0], # } # return ret # def oberfläche(self, selected): # ret = dict() # # das Feld selbst mit dem Selektierten beschreiben # ret['oberflaeche_neu']= selected # pdm_kat = self.model.get_gui_data("pdm_kategorie_neu") # aus_halbzeug = self.model.get_gui_data("aus_halbzeug_neu") # if pdm_kat == 'Einzelteil' and aus_halbzeug is False: # onamen = self.config.Oberfläche.get_oberfläche_of_type(selected) # # setze die Inhalte der abhängigen Comboboxen neu und den Wert im Modell # ret = { # # die neuen Inhalte der comboboxen setzen # 'cb_oberflaeche_neu': onamen, # # der angezeigte Wert der Combos sollte anfangs dem ersten der Liste entsprechen # 'oberflaeche_neu': onamen[0], # } # return ret def cb_farbe_neu(self, selected): farben_alle = self.config.Farben.get_farbauswahl() farben_elox = self.config.Farben.get_farben_eloxieren() # setze die Inhalte der abhängigen Comboboxen neu und den Wert im Modell ret = { # das Feld selbst mit dem Selektierten beschreiben 'farbe_neu': selected, # die neuen Inhalte der comboboxen setzen 'cb_farben': farben_alle, # der angezeigte Wert der Combos sollte anfangs dem ersten der Liste entsprechen 'farbe_neu': farben_alle[0], } return ret if __name__ == "__main__": pass