[Question] StringComboBox im .py Skript füllen | Attribute in der Palette darstellen [Résolu]


Hallo zusammen,

ich arbeite gerade an einem PythonPart, bei dem ich einen Parameter vom Typ StringComboBox mit Werten füllen möchte. Es gibt ja die Möglichkeit in der.pyp-Datei das ganz einfach zu regeln indem man die einzelnen Werte mit einem | voneinander trennt (https://pythonparts.allplan.com/2023/manual/key_components/palette/parameters/parameter_with_combo_box/).
Da in meinem Falls die Werte in der Liste dynamisch sind und je nach Anwendungsfall variieren, möchte ich die Werte für den Parameter in der .py-Datei festlegen. Bei anderen Parametern geht das ja auch recht einfach mit z.B. build_ele.Parameter.value = gewünschter Wert. Bei der StringComboBox bekomme ich es jedoch nur hin den ersten Wert in der Auswahl festzulegen, der Rest bleibt leer.

Eine weitere Frage wäre es, wie ich in der py.-Datei erstellte Attribute in der Palette angezeigt bekomme. Aktuell greif ich auf eine Excel-Tabelle in meinem Skript zu, aus dieser werden dann Informationen extrahiert und dann in Form von Attributen an Bauteile angehängt. Ich attribuiere also mit einem Interactor Part und diesem Workflow bestehende Körper in Allplan. Im Skript steht zum Beispiel:
self.attr_list = []
self.attr_list.append((1905, "C20/25"))
AllplanBaseElements.ElementsAttributeService.ChangeAttributes(self.attr_list, sel_elements)

Das Attribut mit der ID 1905 und dem Wert "C20/25" soll nun in der Eingabepalette dargestellt werden um dem Nutzer in einer Art Übersicht zu zeigen welche Attribute von der Excel Datei alle übertragen und an das Bauteil geheftet werden . Ich habe schon versucht die Informationen an einen Parameter vom Typ AttributeIdValue zu übergeben, aber funktioniert hat das nicht. Gibt es hier vielleicht auch einen Ansatz wie das zu schaffen wäre?

Grüße
Niklas Leipert

Show solution Hide solution

Hallo Niklas,

ich nehme alsso für beide deine Fragen an, dass du einen Interactor PythonPart baust. Ich weiß nicht, wann die "Erstellung" der ValueList erfolgen soll, von daher gehe ich davon aus, dass sie ganz am Anfang erfolgt.

bzgl. deiner erste Frage:
In der .pyp definierts du eine parameter mit string Combobox als ValueType, z.B. so einen:

        <Parameter>
            <Name>DynamicStringComboBox</Name>
            <Text>Dynamic String Combo Box</Text>
            <Value></Value>
            <ValueList>Es ist total egal, was hier definiert ist, weil es eher am skript start überschrieben wird</ValueList>
            <ValueType>StringComboBox</ValueType>
        </Parameter>

Jetzt beim start des skripts willst du die ValueList definiren, deshalb in der __init__ Funktion von deiner Interactor-Klasse muss du den ControlPropertiesUtil starten, so wie in diesem Kapitel beschrieben:

        self.ctrl_props_util = ControlPropertiesUtil(control_props_list,
                                                     build_ele_list)

control_props_list ist der 7. argument deiner __init__ Funktion, und der build_ele_list der 5. Das is vom PythonParts Framework so (sh hier). Jetzt kannst du die ValueList von deinem Parameter überdefinieren:

        self.ctrl_props_util.set_value_list("DynamicStringComboBox", "Erster eintrag|zweiter eintrag|dritter eintrag")

Und jetzt kannst du die Palette starten:

        self.palette_service = BuildingElementPaletteService(build_ele_list,
                                                             build_ele_composite,
                                                             build_ele_list[0].script_name,
                                                             control_props_list,
                                                             build_ele_list[0].pyp_file_name)

        self.palette_service.show_palette(build_ele_list[0].script_name)

        self.palette_service.show_palette(self.build_ele.script_name)

Die selbe Logik kannst du überall in dein Skript implementieren. Bitte immer nach dem verwenden der ControlPropertiesUtil die palette aktualisieren (update_palette() vom BuildingElementPaletteService ausführen). Schau mal in die API reference, was der Util noch kann.

Für deine zweite Frage:
Definiere einen inaktiven AttributeIdValue Parameter als eine leere liste in deiner Palette, so:

        <Parameter>
            <Name>DynamicAttributeList</Name>
            <Text>Attributes</Text>
            <Value>[_]</Value>
            <ValueType>AttributeIdValue</ValueType>
            <Enable>False</Enable>
        </Parameter>

Und in deinem .py Datei die attr_list als eine Python-Liste, die sich aber aus AttributeIdValue-Objekten zusammensetzt:
        self.attr_list: list[AttributeIdValue] = []
        self.attr_list.append(AttributeIdValue(1905,"C20/25"))

weil diese kannst du deinem DynamicAttributeList-Parameter als value zuweisen:
        self.build_ele.DynamicAttributeList.value = self.attr_list

Wenn du danach die Palette initialisierst bzw. aktualisierst, solltest du dort deine Attribute sehen.
Wichtig: die Liste kannst du in der Form nicht direkt an die ChangeAttributes-Methode übergeben. Du musst sie in eine Liste von Tuples umbauen, so:

        AllplanBaseElements.ElementsAttributeService.ChangeAttributes([(attr.attribute_id, attr.value) for attr in self.attr_list], sel_elements)

Und noch Vollständigkeitshalber: die Klasse AttributeIdValue musst du natürlich ganz am Anfang importieren:

from AttributeIdValue import AttributeIdValue

Ich hoffe, damit kommst du weiter.

Grüße, Bart

Hallo Niklas,

ich nehme alsso für beide deine Fragen an, dass du einen Interactor PythonPart baust. Ich weiß nicht, wann die "Erstellung" der ValueList erfolgen soll, von daher gehe ich davon aus, dass sie ganz am Anfang erfolgt.

bzgl. deiner erste Frage:
In der .pyp definierts du eine parameter mit string Combobox als ValueType, z.B. so einen:

        <Parameter>
            <Name>DynamicStringComboBox</Name>
            <Text>Dynamic String Combo Box</Text>
            <Value></Value>
            <ValueList>Es ist total egal, was hier definiert ist, weil es eher am skript start überschrieben wird</ValueList>
            <ValueType>StringComboBox</ValueType>
        </Parameter>

Jetzt beim start des skripts willst du die ValueList definiren, deshalb in der __init__ Funktion von deiner Interactor-Klasse muss du den ControlPropertiesUtil starten, so wie in diesem Kapitel beschrieben:

        self.ctrl_props_util = ControlPropertiesUtil(control_props_list,
                                                     build_ele_list)

control_props_list ist der 7. argument deiner __init__ Funktion, und der build_ele_list der 5. Das is vom PythonParts Framework so (sh hier). Jetzt kannst du die ValueList von deinem Parameter überdefinieren:

        self.ctrl_props_util.set_value_list("DynamicStringComboBox", "Erster eintrag|zweiter eintrag|dritter eintrag")

Und jetzt kannst du die Palette starten:

        self.palette_service = BuildingElementPaletteService(build_ele_list,
                                                             build_ele_composite,
                                                             build_ele_list[0].script_name,
                                                             control_props_list,
                                                             build_ele_list[0].pyp_file_name)

        self.palette_service.show_palette(build_ele_list[0].script_name)

        self.palette_service.show_palette(self.build_ele.script_name)

Die selbe Logik kannst du überall in dein Skript implementieren. Bitte immer nach dem verwenden der ControlPropertiesUtil die palette aktualisieren (update_palette() vom BuildingElementPaletteService ausführen). Schau mal in die API reference, was der Util noch kann.

Für deine zweite Frage:
Definiere einen inaktiven AttributeIdValue Parameter als eine leere liste in deiner Palette, so:

        <Parameter>
            <Name>DynamicAttributeList</Name>
            <Text>Attributes</Text>
            <Value>[_]</Value>
            <ValueType>AttributeIdValue</ValueType>
            <Enable>False</Enable>
        </Parameter>

Und in deinem .py Datei die attr_list als eine Python-Liste, die sich aber aus AttributeIdValue-Objekten zusammensetzt:
        self.attr_list: list[AttributeIdValue] = []
        self.attr_list.append(AttributeIdValue(1905,"C20/25"))

weil diese kannst du deinem DynamicAttributeList-Parameter als value zuweisen:
        self.build_ele.DynamicAttributeList.value = self.attr_list

Wenn du danach die Palette initialisierst bzw. aktualisierst, solltest du dort deine Attribute sehen.
Wichtig: die Liste kannst du in der Form nicht direkt an die ChangeAttributes-Methode übergeben. Du musst sie in eine Liste von Tuples umbauen, so:

        AllplanBaseElements.ElementsAttributeService.ChangeAttributes([(attr.attribute_id, attr.value) for attr in self.attr_list], sel_elements)

Und noch Vollständigkeitshalber: die Klasse AttributeIdValue musst du natürlich ganz am Anfang importieren:

from AttributeIdValue import AttributeIdValue

Ich hoffe, damit kommst du weiter.

Grüße, Bart

Hallo Bart,

ich konnte mit deinen Tipps mal wieder alles Gewünschte und sogar noch ein paar Kleinigkeiten mehr erreichen, vielen Dank dafür!


https://campus.allplan.com/ utilise des cookies  -  Plus d'informations

Accepter