in reply to unique identifiers for gtk2 canvas objects?
Use hashes. I do it all the time in Tk(I'm just dabbling in gtk2). You just need to be careful when setting up your keys. Some tips: Don't use your object as a key. For example ( a pseudo code NOT gtk2 syntax ):
Once you get the tags from an object, you can domy %rects; my %ovals; for my $num(1..10){ $rects{$num}{'object'} = $canvas->createRect( ...... -tags => [$num , 'rect' ] ); $rects{$num}{'num'} = $num; $rects{$num}{'mydata2'} = "some array or HoA" $rects{$num}{'object'}->bind('Enter',sub{ print "$num\n" }); } for my $num(1..10){ $ovals{$num}{'object'} = $canvas->createOval( ...... -tags => [$num , 'oval' ] ); $ovals{$num}{'num'} = $num; $ovals{$num}{'mydata2'} = "some array or HoA" }
You can setup the hashes depending on what you need to do. The above is just a simple example. Just setup your tags to give you and identifier for the "current" selected item. Now you can setup bindings for "current" to get what the tags are for whatever the mouse is in.my $data = $ovals{$num_from_tags}{'mydata2'}
Here is an example from one of the Perl-Gtk2 tutorials. It shows how to add data to a gtk2 object. The idea is similar to what I've described above.(Look for the lines "#Add user data"
#!/usr/bin/perl ############################################################ # Example of animation on the gnome canvas. # # Dov Grobgeld ############################################################ use Gtk2 '-init'; use Gnome2::Canvas; use strict; my ( $w_top, $w_canvas ); my $min_x = 5; my $max_x = 500; my ( $rect_green, $rect_orange ); ############################################################ # Create the widgets ############################################################ sub create_widgets { $w_top = Gtk2::Window->new; $w_top->signal_connect( destroy => sub { exit } ); my $vbox = Gtk2::VBox->new( 0, 0 ); $w_top->add($vbox); $w_canvas = Gnome2::Canvas->new_aa(); $vbox->pack_start( $w_canvas, 1, 1, 0 ); $w_canvas->set_size_request( 600, 300 ); $w_canvas->set_scroll_region( 0, 0, 600, 300 ); my $quit = Gtk2::Button->new("Quit"); $quit->signal_connect( clicked => sub { exit } ); $vbox->pack_start( $quit, 0, 0, 0 ); $w_top->show_all(); } sub place_objects_on_canvas { my $root = $w_canvas->root(); $rect_green = Gnome2::Canvas::Item->new( $root, "Gnome2::Canvas::Rect", x1 => 240, y1 => 90, x2 => 440, y2 => 180, fill_color_rgba => 0x3cb37180, outline_color => "black", width_units => 2.0 ); # Add user data $rect_green->{dir} = 1; $rect_green->{speed} = 5; $rect_orange = Gnome2::Canvas::Item->new( $root, "Gnome2::Canvas::Ellipse", x1 => 30, y1 => 150, x2 => 250, y2 => 240, fill_color_rgba => 0xb3713c80, outline_color => "black", width_units => 2.0 ); $rect_orange->{dir} = -1; $rect_orange->{speed} = 8; Glib::Timeout->add( 10, \&cb_animation_step ); } ############################################################ # Takes one step of the animation. rect_green is moved by # DELTA_Y_GREEN and rect_orange by DELTA_Y_ORANGE. When they # meet the borders, their direction change ############################################################ sub cb_animation_step { foreach my $r ( $rect_green, $rect_orange ) { # Get old values my ( $old_x1, $old_x2 ) = $r->get( "x1", "x2" ); # Get user data my $dir = $r->{dir} || 1; my $speed = $r->{speed}; # Move the object my $new_x1 = $old_x1 + $dir * $speed; my $new_x2 = $old_x2 + $dir * $speed; # Check if we hit a wall if ( $new_x1 < $min_x || $new_x2 > $max_x ) { $dir = -$dir; $r->{dir} = $dir; $new_x1 = $old_x1 + $dir * $speed; $new_x2 = $old_x2 + $dir * $speed; } # Update new parameter data $r->set( x1 => $new_x1, x2 => $new_x2 ); } # As long as this routine returns TRUE, it will be # called again return 1; } create_widgets(); place_objects_on_canvas(); Gtk2->main();
|
|---|