Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Tk::Canvas createGroup() Undocumented

by kcott (Bishop)
on Mar 20, 2021 at 12:16 UTC ( #11130002=perlquestion: print w/replies, xml ) Need Help??

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:

  • The Tk::Canvas documentation has no mention of createGroup().
  • The Github repo ( does show group, along with other create methods (arc, oval, window, etc.) but there's no code for me to study (looks like it's probably in XS-code).
  • "Active bugs for Tk" has no mention of missing documentation.
  • An internet search was not helpful: mostly links to the online documentation I'd already looked at, and the online pirated versions of "Mastering Perl/Tk".

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:

#!/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) { my $grassy_creek = $c->createGroup( [0,0], -members => [grass($c), creek_we($c)] ); $mw->update(); $c->move($grassy_creek, $x, 100); } my $grassy_creek_bend = $c->createGroup( [0,0], -members => [ grass($c), creek_half_w($c), creek_half_s($c), creek_bend_ws($c), ] ); $mw->update(); $c->move($grassy_creek_bend, 200, 100); MainLoop; sub grass { return $_[0]->createRectangle( 0, 0, 100, 100, -fill => '#009900', -outline => undef ); } sub creek_we { return $_[0]->createRectangle( 0, 30, 100, 70, -fill => '#0000cc', -outline => undef ); } sub creek_half_w { return $_[0]->createRectangle( 0, 30, 50, 70, -fill => '#0000cc', -outline => undef ); } sub creek_half_s { return $_[0]->createRectangle( 30, 50, 70, 100, -fill => '#0000cc', -outline => undef ); } sub creek_bend_ws { return $_[0]->createArc( 30, 30, 70, 70, -fill => '#0000cc', -outline => undef ); }

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

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11130002]
Approved by hippo
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2021-05-06 12:50 GMT
Find Nodes?
    Voting Booth?
    Perl 7 will be out ...

    Results (74 votes). Check out past polls.