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

[email protected] (Jeff Hobbs) Wed, 27 Oct 2010 18:37:07 -0700
Newsgroups perl.tcltk
Message-ID <[email protected]>
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?

Jeff
table.pl (text/plain, 420 B)
use strict;
use warnings;
use Tkx;

Tkx::package_require("Tktable");

my $mw = Tkx::widget->new(".");
my %hash;
tie %hash, 'Tcl::Var', Tkx::i::interp(), "myarray";
%hash = ( # data to display
  '1,1' => 'Goodby',
  '2,2' => 'cruel',
  '3,3' => 'world',
);
my $t = $mw->new_table(
    -rows => 5,
    -cols => 3,
    -cache => 1,
    -variable => "myarray",
);
$t->g_pack(-fill => 'both', -expand => 1);
Tkx::MainLoop();