Re: How to use a tcl/tk widget that needs a tcl array

[email protected] (Gisle Aas) Thu, 28 Oct 2010 21:51:22 +0200
Newsgroups perl.tcltk
Message-ID <[email protected]>
On Oct 28, 2010, at 3:37 , Jeff Hobbs wrote:

> On 2010-10-22, at 10:01 AM, Lindley, Robert A wrote:
>> I would like to use the tktable widget, but can't find any information on how to pass something as the -variable option and be able to display and retrieve data.
>> 
>>   use Tkx;
>>   Tkx::package_require("Tktable");
>> 
>>   my $mw = Tkx::widget->new(".");
>>   my $t = $mw->new_table(
>>       -rows => 5,
>>       -cols => 3,
>>   );
>>   $t->g_pack;
>> 
>>   Tkx::MainLoop()
>> 
>> I found the above in the ActiveState documentation. It works as expected.
>> 
>> All attempts to display or retrieve data have failed.
> 
> So in working with Bob to address this, I found that there is a key missing feature in Tkx to support the final solution - obtaining the $interp used by Tkx.
> 
> My first point was that the table by default needs a data source. The easiest is to use '-cache => 1' to say cache data in memory. To tie it to a hash, you need to use tie and reference the tied name in Tcl (.e.g -variable => 'myarray').  It turns out the docs for Tcl.pm are incorrect in not quoting Tcl::Var, but it would look like this:
> 
> tie %hash, 'Tcl::Var', $interp, "myarray";
> 
> The real problem though is how do you get $interp from Tkx?  It looks like you don't.  It's a 'my' var in Tkx::i namespace, and the rest of the package handily abstracts everything so neatly that you don't need access to $interp.  EXCEPT in this one case.  I patched Tkx to have
> 
> sub interp { return $interp; }
> 
> in the Tkx::i namespace, which would allow:
> 
> tie %hash, 'Tcl::Var', Tkx::i::interp(), "myarray";
> 
> and checked that this does work with the attached sources.  The question is, is this the correct answer?  Should Tkx have a different redirect for 'tie', or should there be another way to get the $interp reference that Tkx uses?
> 
> Gisle - any thoughts on this?

The $interp is hidden because I simply did not want to expose any of the Tcl.pm interface.  I wanted Tkx to stand on its own, be easy to grok, and be documented without reference to Tcl.pm.  That would also allow a potential future development where Tkx embeds libtcl directly instead of adaping the Tcl.pm interfaces and its quirks.  This isn't likely to happen any time soon, so I don't mind adding a (undocumented) Tkx::i::interp() function for the cases where you need direct access.

For this specific problem I think we should just make passing of a hash reference to a Tcl command work the same way it works to pass a scalar reference.  It should then be possible to just use:

my %hash = ( # data to display
  '1,1' => 'Goodby',
  '2,2' => 'cruel',
  '3,3' => 'world',
);
my $t = $mw->new_table(
    -rows => 5,
    -cols => 3,
    -variable => \%hash,
);

I'll play around a bit to figure if I can make that work easily.

Regards,
Gisle