http://www.perlmonks.org?node_id=11130002

kcott has asked for the wisdom of the Perl Monks concerning the following question:

G'day All,

Background: I've been playing around in Tk, looking at the feasibility of using Tk::Canvas to generate some simple, interactive maps for use with RPGs. I came across the createGroup() method, which would help enormously with abstraction and code reduction; however, I'm unable to find any substantial documentation for this.

I found this method in "Mastering Perl/Tk" (Chapter 9: The Canvas Widget; The Group Item; pp. 212-213). Over half of that is taken up with a couple of screenshots. There's a minimal code example, with very little explanation, which looks like:

$one = $canvas->createOval(...); $two = $canvas->createRectangle(...); $group = $canvas->createGroup([0, 0], -members => [$one, $two]); $mw->update; $mw->after(1000); $canvas->move($group, 100, 100);

I've no idea what the [0, 0] is supposed to do. My first thought was that it was related to placement; but, after putting all sorts of different numbers in there, I see no change. It's also unclear why the update() is necessary — but it is.

I've checked for documentation, or other references, in the following places:

I put together the following test script. This was mainly to check that what was written in the book was valid.

#!/usr/bin/env perl use strict; use warnings; use Tk; my $mw = MainWindow::->new(); my $scrl_can = $mw->Scrolled('Canvas', -scrollregion => [0, 0, 300, 300], )->pack(qw{-fill both -expand 1}); my $c = $scrl_can->Subwidget('canvas'); for my $x (0, 100, 200) { my $grassy_creek = $c->createGroup( [0,0], -members => [grass($c), creek($c)] ); $mw->update(); $c->move($grassy_creek, $x, 100); } MainLoop; sub grass { return $_[0]->createRectangle( 0, 0, 100, 100, -fill => '#009900', -outline => undef ); } sub creek { return $_[0]->createRectangle( 0, 30, 100, 70, -fill => '#0000cc', -outline => undef ); }

That worked: I got (using a modicum of imagination) a creek running through a grassy area (three blocks wide). That's the type of abstraction I was looking for but I still wasn't happy with the cargo-cult programming.

I wondered if the ARRAYREF ([0, 0]) had something to do with the number of members in the group. I put a bend in the last part of the creek using a group with four members; this worked, still with [0, 0]. Here's the important part of the code for that test:

my $grassy_creek_bend = $c->createGroup( [0,0], -members => [ grass($c), creek_half_w($c), creek_half_s($c), creek_bend_ws($c), ] );

The full code is somewhat lengthy; it's in the following spoiler:

I'm using Perl 5.32.0 and Tk 804.035.

So, this leads to the questions. Can anyone point me to any documentation about this? In the absence of doco, does anyone have an explanation for the [0, 0] and the need for the update()?

Thanks in advance.

— Ken

Replies are listed 'Best First'.
Re: Tk::Canvas createGroup() Undocumented
by bliako (Prior) on Mar 20, 2021 at 19:01 UTC

    Hi Ken,

    This probably can shed some light, from TK Canvas: Group vs. tags:

    For instance, if you tried to rotate a bunch of "tags", they would all + rotate independently; but if they are grouped, you can specify the g +roup center point, where they would rotate around.

    So, my guess would be that (0,0) is the group's "handle" point for geometric transformations.

    bw, bliako

      G'day bliako,

      ++ Thanks for taking the trouble to dig out that old (2004) post.

      The text regarding rotations from zentara (which you've quoted) actually refers to Tk::Zinc; rotations are not possible with Tk::Canvas. From "Tk::Canvas - TRANSFORMATIONS":

      ... Canvases do not support scaling or rotation of the canvas coordinate system relative to the window coordinate system.

      Individual items may be moved or scaled using methods described below, but they may not be rotated.

      The thinking behind your guess is valid; unfortunately, it cannot work.

      That's a pity because it would have been useful. For instance, rotating the bend through 90 clockwise, could have made the creek flow north, instead of south, without the need to code a separate group. Presumably, had that been possible, the [0, 0] would have needed to be [50, 50] to rotate about the centre.

      — Ken

Re: Tk::Canvas createGroup() Undocumented
by kcott (Bishop) on Mar 27, 2021 at 12:30 UTC

    A lot of guesses, by me and ++bliako: no resolution.

    I was tempted to raise as doco/bug issue: the current target being "Active bugs for Tk", but that is shutting down in a couple of days. I'll wait and see what happens.

    I'm still using this function. I did determine a number of things. Two things of note:

    • An update of the UI ($mw->update) is entirely unecesssary; an update is necessary, but only of the canvas ($canvas->update()).
      Depending on your use case, you may be able to exploit the ability to compose individual items, as well as groups, into a single group. I found this to be useful, YMMV.

    — Ken