Is it possible to change tha value of a field in the tree, from a tcl procedure and update its value in the tree?
If it is, can you provide an simple example.
the data tree is stored in a XML DOM structure, and the window treectrl is filled from this data.
using the tdom package (
https://docs.activestate.com/activetcl/8.6/tcl/tdom
) you can access to this data
https://gidsimulation.atlassian.net/wik ... nformation
load the problemtype Examples/cmas2d_customlib
you will see a tree like this
you can see the XML of his DOM with a command like this:
-np- W [[$::gid_groups_conds::doc documentElement] asXML]
rials" pn="Edit materials" icon="darkorange-block1.png" proc="Cmas2d::EditDatabaseListDirect %W %DICT %BC"/>
</value>
</condition>
<container n="materials" pn="Materials" icon="darkorange-block1" help="Materials database">
<blockdata n="material" name="Air" sequence="1" editable_name="unique" icon="darkorange-wind-sign" help="Material definition" morebutton="0">
<value n="Density" pn="Density" v="1.01" help="Superficial density assuming a thickness of 1 meter" unit_magnitude="M/L^2" units="kg/m^2"/>
</blockdata>
<blockdata n="material" name="Steel" sequence="1" editable_name="unique" icon="darkorange-bracket" help="Material definition" morebutton="0">
<value n="Density" pn="Density" v="7850" help="Superficial density assuming a thickness of 1 meter" unit_magnitude="M/L^2" units="kg/m^2"/>
</blockdata>
<blockdata n="material" name="Aluminium" sequence="1" editable_name="unique" icon="darkorange-alu" help="Material definition" morebutton="0">
<value n="Density" pn="Density" v="2650" help="Superficial density assuming a thickness of 1 meter" unit_magnitude="M/L^2" units="kg/m^2"/>
</blockdata>
</container>
</container>
<display_options frame_width="321" is_frame_open="1" view_conditions_search="1" conditions_search_values="" frame_side="left"/>
<global_preferences>
<units>
<unit_magnitude_user_sel n="M" values="kg"/>
<unit_magnitude_user_sel n="L" values="m"/>
<unit_mesh n="m"/>
</units>
<tree_preferences/>
</global_preferences>
</cmas2d_customlib_data>
If do you want for example ask for the 'Density' of the material named 'Steel' , can see in the XML that in this problemtype the materials are in a node named 'container' with an attribute 'n' with value 'materials' and then several child nodes named 'blockdata' with an attribute 'n' with value 'material' and we want the one that match the attribute 'name' that we want to ask.
then we use an xpath like this
set x_path "//container\[@n='materials'\]/blockdata\[@n='material' and @name='$material'\]"
and inside there are sub-childs with name= 'value for each question, and we want the one with attribute 'n' equal to our question to ask
set x_path_3 ".//value\[@n='$question'\]"
can define these procedures
proc my_get_dom_nodes { xpath } {
set doc $gid_groups_conds::doc
set root [$doc documentElement]
set dom_nodes [$root selectNodes $xpath]
return $dom_nodes
proc my_get_material { material question } {
set value ""
set x_path "//container\[@n='materials'\]/blockdata\[@n='material' and @name='$material'\]"
set dom_material [my_get_dom_nodes $x_path]
if { [llength $dom_material] != 1 } {
error "Error: material '$material' not found"
} else {
set x_path_3 ".//value\[@n='$question'\]"
set dom_node [lindex [$dom_material selectNodes $x_path_3] 0]
if { $dom_node == "" } {
error "GiD_AccessValue: property $question not found in material $material"
set value [$dom_node getAttribute v ""]
return $value
and use it like this: -np- W [my_get_material Steel Density]
and will get the value
if do you want to set its value, can define another procedure like this:
proc my_set_material { material question value } {
set x_path "//container\[@n='materials'\]/blockdata\[@n='material' and @name='$material'\]"
set dom_material [my_get_dom_nodes $x_path]
if { [llength $dom_material] != 1 } {
error "Error: material '$material' not found"
} else {
set x_path_3 ".//value\[@n='$question'\]"
set dom_node [lindex [$dom_material selectNodes $x_path_3] 0]
if { $dom_node == "" } {
error "GiD_AccessValue: property $question not found in material $material"
$dom_node setAttribute v $value
return $value
and use it like this to set to other value: -np- W [my_set_material Steel Density 8200.5]
and to refresh the tree widget is possible to use something like this (simple but expensive because will destroy and rebuild the whole widget) -np-GidUtils::UpdateWindow CUSTOMLIB
Thanks for the reply.
In regard to the update of the tree, the command gid_groups_conds::actualize_conditions_window is less "expensive" than the proposed GidUtils::UpdateWindow ?
Best regards
They will have similar cost,
in fact GidUtils::UpdateWindow CUSTOMLIB will call gid_groups_conds::actualize_conditions_window
I recommend you use GidUtils::UpdateWindow instead directly gid_groups_conds::actualize_conditions_window
because it use a common centralized syntax to update several windows (CUSTOMLIB, GROUPS, LAYER, ...)
and the same for
GidUtils::OpenWindow, GidUtils::CloseWindow, GidUtils::ExistsWindow, GidUtils::ToggleWindow
(see comments on <GiD>\scripts\dev_kit.tcl to know the names of windows for these hight level functions)
If you do several changes of the tree and do a final update the cost doesn't matter, but don't update it after each change, in this case must use some lower level function to not rebuild the whole tktreectrl widget)