Sunday, December 22, 2013

tcl: dumping tablelist data

For the tablelist widget I created a function to dump the table content to a file

proc dumpTableListToFile { tree { file preview.txt } } { 
set rowCount [$tree size]
set file_writer [open $file w+]
for { set i 0 } { $i < $rowCount } { incr i } {
set rowData [$tree get $i]
puts $file_writer $rowData
}
close $file_writer
}


parameters:



tree, is the table widget, file is the file name, optional.

Monday, December 16, 2013

tcl: find widget recursively

I was doing some testing for multi container application, and same widget could exist in different containers and could have variable parent name, I created a function to find the widget recursively by the last portion of the widget name
The function I initially created
   1: proc findWidgetByName { wname {widget .mainwindow} } {    
   2:     set pattern "*.${wname}" 
   3:     #puts $widget    
   4:     set all "[winfo children $widget]" 
   5:     foreach child $all  { 
   6:         #puts "$child" 
   7:         if { [winfo viewable $child] && [string match $pattern $child] } { 
   8:                 #puts $child 
   9:                 return $child            
  10:         } else { 
  11:             return [findWidgetByName $wname $child]        
  12:         } 
  13:     } 
  14:     return 0 
  15: }

Testing the above function, it was taking the first child in each “for loop” and returning without checking other childs, with the help of my colleague, we changed it to working version

   1: proc findWidgetByName { wname {widget .mainwindow} } {    
   2:     set pattern "*.${wname}" 
   3:     #puts $widget    
   4:     set all "[winfo children $widget]" 
   5:     foreach child $all  { 
   6:         #puts "$child" 
   7:         if { [winfo viewable $child] && [string match $pattern $child] } { 
   8:                 #puts $child 
   9:                 return $child            
  10:         } else { 
  11:             set x [findWidgetByName $wname $child]        
  12:             if {  $x !=0 } { 
  13:             return $x ;            
  14:             } 
  15:         } 
  16:     } 
  17:     return 0 
  18: }

When using for loops with recursion we need to put some condition when to break the for loop execution
I have created also another version to find widgets by label, in case of buttons or labels

   1: proc findWidgetByLabel { label {widget .mainwindow} } {       
   2: set all "[winfo children $widget]"
   3:     foreach child $all  {
   4:         #puts "$child"
   5:         if {([winfo class $child]== "Label" || [winfo class $child]== "Button" ) && [winfo viewable $child] && [$child cget -text]==$label } {
   6:                 #puts $child
   7:                 return $child            
   8:         } else {
   9:             set x [findWidgetByLabel $label $child]        
  10:             if {  $x !=0 } {
  11:                 return $x ;            
  12:             }
  13:         }
  14:     }
  15:     return 0
  16: }

Same can be applied to find widget by any property

Friday, December 13, 2013

Extracting tcl treeview items

I wanted to validate treeview items after doing operations on them, like add, delete. I created 2 function to extract the items and dump into a file, next i was able to compare the extracted file with the expected values

#this function dumps the 1st level in the tree to a file
proc dumpTreeDataTags { file } {
global treeControl
    set file_writer [open $file  w+]
foreach id [$treeControl item children root] {
   set data [$treeControl item tag names $id]
   puts $file_writer $data
}
    close $file_writer
}

#this function dumps all the tree data, file is appended. File must be cleared before calling this function
proc dumpAllTreeDataTags { file { item root} } {
    global treeControl
foreach id [$treeControl item children $item] {
   set file_writer [open $file  a+]
   set data [$treeControl item tag names $id]
   puts $file_writer $data
   close $file_writer
   dumpAllTreeDataTags $file $id
}
}

Explaining the functions:
The first one, i am extracting the first level only, and saving to the file, the file is opened in write mode, and replaced every time the function is called.
The second function is using recursion to iterate starting from the root node, through the children, and then calling the function again for each children, and so on. File is opened in append mode, so that when called in recursion, the previous data written to the file is not lost