[Frage] Verkettung von Handles mit zweidimensionalen List-Parametern

Schlagworte:
  • PythonParts
  • Handles
  • Matrix
  • Parameter
  • List

Servus zusammen!
Ich habe folgende Aufgabe: eine Makro-Gruppe (bzw. PythonPart-Gruppe) aus mehreren, identischen Makros in einem regelmäßigen Raster zu erzeugen, jedoch mit der Möglichkeit, einzelne Makros in diesem Raster ausschalten zu können. Dafür habe ich folgenden Parameter definiert

<Parameter>
	<Name>Create_macro</Name>
	<Text>Makro erzeugen ja/nein</Text>
	<Value>[[True, True], [True, True]]</Value>
	<ValueType>CheckBox</ValueType>
	<Dimensions>Count_z,Count_y</Dimensions>
</Parameter>

Wo Count_z und Count_y die Anzahl der Elemente in entsprechender Richtung definieren, die aber in einem anderen Integer-Parameter definiert sind. So weit so gut - der Parameter erscheind richtig in der Palette und mach seine Aufgabe.

Mein Problem beginnt, wenn ich einen Click-Handle erzeugen will, um diesen Parameter zu steuern. Denn in der Dokumentation der Klasse HandleParameterData steht, dass man den Handle schon mit einem konkreten Element des List-Parameters verknüpfen kann, den man in dem Argument list_index angibt:

class HandleParameterData.HandleParameterData(param_prop_name: str,
                                               param_type: HandleParameterType,
                                               has_input_field: bool = True,
                                               show_negative_value: bool = False,
                                               check_box_state: bool = True,
                                               in_decrement_value: Any = 1,
                                               list_index: Optional[int] = None)

Aber der Index muss als Integer angegeben werden. Mit eindimensionalen List-Parameter funktioniert es, aber um auf einen Element eines zweidimensionalen List-Parameters zuzugreifen, muss ich doch den Index mit zwei Integer definieren - die Spalten- und Zeilennummer. Wenn ich das Probiere, mit folgendem Syntax:

 creation_handle_parameter_data = HandleParameterData (param_prop_name     = "Create_macro",
                                                       param_type          = HandleParameterType(13),
                                                       list_index          = [i,j])

Wo i und j Integer sind, bekomme ich folgende Meldung im Trace:
Traceback (most recent call last):
  File "C:\ProgramData\Nemetschek\Allplan\2022\Etc\PythonPartsFramework\GeneralScripts\BuildingElementInput.py", line 686, in process_mouse_msg
    BuildingElementInputService.move_handle(self, AllplanGeo.Point3D())
  File "C:\ProgramData\Nemetschek\Allplan\2022\Etc\PythonPartsFramework\GeneralScripts\BuildingElementInputService.py", line 189, in move_handle
    handle_result = input_data.build_ele_script.move_handle(input_data.build_ele_list[0],   \
  File "C:\Data\Allplan\2022\Std\PythonPartsScripts\MyPythonParts\Macros_grid.py", line 49, in move_handle
    build_ele.change_property(handle_prop, input_pnt)
  File "C:\ProgramData\Nemetschek\Allplan\2022\Etc\PythonPartsFramework\GeneralScripts\BuildingElement.py", line 657, in change_property
    not PropertyUtil.get_property_value(prop, item_name))
  File "C:\ProgramData\Nemetschek\Allplan\2022\Etc\PythonPartsFramework\GeneralScripts\BuildingElementParameterPropertyUtil.py", line 633, in get_property_value
    return eval(name.replace("(", "[").replace(")", "]"),
  File "<string>", line 1, in <module>
TypeError: list indices must be integers or slices, not list

Mache ich etwas falsch in dem Syntax, oder ist das einfach nicht machbar?

Man kann jedes mehrdimensionale Array in ein eindimensionales umwandeln. (Im Speicher liegt es ja auch mit nur "einer Dimension")

Also einfach eine Funktion schreiben, die i und j in einen eindimensionalen Index umrechnet, und die Sache funktioniert.

Hallo,

das Problem ist in der kommenden 2022-1-5 behoben. Zum Test in

../etc/PythonPartsFramework/GeneralScripts/BuildingElement.py

den Block

if param_data.list_index is not None:
item_name += "[" + str(param_data.list_index) + "]"

durch

if (list_index := param_data.list_index) is not None:
item_name += "[" + str(list_index) + "]" if not isinstance(list_index, list) else \
"[" + "][".join([str(index) for index in list_index]) + "]"

ersetzen.

Viele Grüße
Horst

Zitiert von: Horst_Hohmann
Hallo,
das Problem ist in der kommenden 2022-1-5 behoben. Zum Test in
../etc/PythonPartsFramework/GeneralScripts/BuildingElement.py
den Block...

Das hat sofort funktioniert! Ich habe schon gedacht, dass ich beim Syntax etwas verkehrt mache. Vielen Dank und wir warten dann auf die Version 2022-1-5!

Zitiert von: Nemo
Man kann jedes mehrdimensionale Array in ein eindimensionales umwandeln. (Im Speicher liegt es ja auch mit nur "einer Dimension")
Also einfach eine Funktion schreiben, die i und j in einen eindimensionalen Index umrechnet, und die Sache funktioniert.

Ich könnte es in dem Fall machen. Das würde aber bedeuten, dass ich mein Create_macro-Parameter vom Anfang an eindimensional definieren muss. Und dann erscheint er in der Palette als eine Reihe von Check Boxen. Dann musste ich den in der Palette ausblenden, denn er würde dem Anwender ehe nicht viel bringen, weil kein optischer Zusammenhang mehr besteht. Man hat also die Wahl: entweder Handle oder Palette. Aber wenn das Problem in 2022-1-5 behoben wird, dann muss man sich nicht entscheiden.

Ich dachte, bei obigem Beitrag ging es nur um die "Klick-Handles"!

Wozu braucht man zusätzlich noch ein (2-dimensionales) "Array von Checkboxen" in der Palette ?

Ich kenne zwar das PythonPart nicht, aber ich würde wahrscheinlich immer auf das Handle im Preview klicken,
statt in der Palette Zeilen und Spalten zu zählen.

Zitiert von: Nemo
Ich dachte, bei obigem Beitrag ging es nur um die "Klick-Handles"!
Wozu braucht man zusätzlich noch ein (2-dimensionales) "Array von Checkboxen" in der Palette ?
Ich kenne zwar das PythonPart nicht, aber ich würde wahrscheinlich immer auf das Handle im Preview klicken,
statt in der Palette Zeilen und Spalten zu zählen.

In dem konkreten PythonPart handelt es sich um Spannlitzen mit sofortigem Verbund. Diese werden in der Regel in einem orthogonalen Raster verlegt, aber eben nicht in allen Schnittpunkten des Rasters. I.d.R. bis zu 5 Lagen mit bis zu 7 Litzen pro Lage. Und ich wollte eben dem Anwender die Möglichkeit geben, die einzelne Litzen sowohl in der Palette, als auch im Modell über Handles aus- und einzuschalten. Dafür ist eben ein 2-dimensionaler Array aus Checkboxen in der Palette perfekt, denn es ordnet sich selbst in einen "Listen-Raster" an