Updated 2014-01-20 12:49:25 by RLE

Hopefully someone will fill in some code here demonstrating how one can save off all an application's widgets in such a way that the next time the application is invoked, it looks just like it did when the save occured.

One would then invoke this code at various event points in the application (when the user resizes a widget, changes a color or language, etc.) so that they have a rather seamless environment.

Try a widget serializer

male - 2003-06-23:

Sorry, but why don't we think about integrating serializibility in the core?

Sometimes I really would like to be able to serialize an UI or parts of an UI!

One possiblity would be to have serialize commands for each widget to generate widgets serialization data, that could be saved into a file.

This serialization data could be ...

  • ascii data containing a tcl script configuring the widget with the needed data, recreating embedded windows like images in canvas or text widgets.
  • binary data containing bytecode of the tcl script contained by the ascii data described above

To restore widgets it would be only needed to source or eval(uate) the serialization data.

To bring the restore nearer to the serialized widgets a "restore" command could be added to widgets.

An example:
 proc serialize {widget path} {
   set serializeData {};
   
   foreach childWidget [winfo children $widget] {
     lappend serializeData [$childWidget serialize];
   }
 
   set fid [open [file join $path $widget.SerializeData] w];
   puts $fid [join $serializeData ";"];
   close $fid;

   return;
 }


 proc restore {widget path} {
   source [file join $path $widget.SerializeData];

   return;
 }

or
 proc restore {widget path} {
   $widget restore [file join $path $widget.SerializeData];

   return;
 }

A addition could be to add an serialize/restore subcommand to the winfo command accepting only toplevels to easy up the serialization of complete UIs.

The serialize subcommand would collect and return serialization data from the toplevel itself and the whole widget tree below the given toplevel. The restore subcommand would restore/recreate the toplevel and the stored widget tree below the given toplevel.

An example:
 proc serialize {widget path} {
   if {[winfo toplevel $widget] != $widget} {
     set serializeData {};
   
     foreach childWidget [winfo children $widget] {
       lappend serializeData [$childWidget serialize];
     }

     set serializeData [join $serializeData ";"];
   } else {
     set serializeData [winfo serialize $widget];
   }
 
   set fid [open [file join $path $widget.SerializeData] w];
   puts $fid $serializeData;
   close $fid;

   return;
 }

 proc restore {widget path} {
   if {[winfo toplevel $widget] == $widget} {
     winfo restore $widget [file join $path $widget.SerializeData];
   } else {
     $widget restore [file join $path $widget.SerializeData];
   }

   return;
 }

And to take to the top - what's about a clone (sub)command for each widget or toplevels like the serialize (sub)command described above?

See also Automatically save widget values by traversing object tree