Thread Tk-Raten: Linie zwischen zwei Boxen ziehen
(3 answers)
Opened by pktm at 2010-09-05 16:05
Hallo Molaf,
den Code würde ich mir gerne mal ansehen. Hier ist das, was ich gestern Abend und heute Abend so hinbekommen habe. Der Code zum Auslesen einer ID, die als Tag hinterlegt wurde, muss noch gekapselt werden, aber ich denke, damit komme ich ganz gut hin. Es fehlt noch: - diese Kapselung... - Ursprungs-Widget-ID merken - Linie zwischen den Widgets malen (ich will die gezogene nicht einfach stehen lassen, sondern eine ordentliche von der Mitte rechten Randes des linken Widgets zur Mitte des linken Rands des rechten Widgets ziehen). Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 #!/usr/bin/perl use strict; use warnings; use Data::Dumper qw/Dumper/; use Tk; my $mw = tkinit(); my $canvas = $mw->Canvas()->pack(-expand => 1, -fill => 'both',); # ------------------------------------------------------------- # --- left box my $left = $canvas->createText( 50, 50, -text => 'left', -tags => [qw/left text id1/] ); my @left_bbox = $canvas->bbox('left', 'id1'); my $padding = 3; $canvas->createRectangle( $left_bbox[0] - $padding, $left_bbox[1] - $padding, $left_bbox[2] + $padding, $left_bbox[3] + $padding, -fill => 'green', -tags => [qw/left box id1/] ); $canvas->raise('text', 'box'); # ------------------------------------------------------------- # --- right box my $right = $canvas->createText( 250, 50, -text => 'right', -tags => [qw/right text id5/] ); my @right_bbox = $canvas->bbox('right', 'id5'); $canvas->createRectangle( $right_bbox[0] - $padding, $right_bbox[1] - $padding, $right_bbox[2] + $padding, $right_bbox[3] + $padding, -fill => 'yellow', -tags => [qw/right box id5/] ); $canvas->raise('text', 'box'); # -- store point of origin here: my $origin_x = undef; my $origin_y = undef; $canvas->bind('left', '<Button-1>' , [ sub{ start_drawing_xy(@_); }, Ev('x'), Ev('y'), \$origin_x, \$origin_y ]); $canvas->Tk::bind('<B1-Motion>' , [ sub{ motion_xy(@_); }, Ev('x'), Ev('y'), \$origin_x, \$origin_y ]); $canvas->Tk::bind('<ButtonRelease>' , [ sub{ stop_drawing_xy(@_); }, Ev('x'), Ev('y'), \$origin_x, \$origin_y ]); $mw->MainLoop(); =head2 start_drawing_xy( $canvas, $x, $y, \$origin_x, \$origin_y ) =cut sub start_drawing_xy { my $canvas = shift; my $x = shift; my $y = shift; my $origin_x = shift; my $origin_y = shift; $$origin_x = $x; $$origin_y = $y; printf("init drawing from vertex <%s, %s>\n", $x, $y); } # /start_drawing_xy =head2 motion_xy( $canvas, $x, $y ) Draw a line from source vertex to current vertex. Current vertex is the vertex of the current mouse cursor position while button 1 is pressed. =cut sub motion_xy { my $canvas = shift; my $x = shift; my $y = shift; my $origin_x = shift; my $origin_y = shift; # catch unset origin return unless $$origin_x; # -- delete old line $canvas->delete('line'); # -- draw new line $canvas->createLine($$origin_x, $$origin_y, $x, $y, -tags => [qw/line/]); printf("draw line from source vertex <%s, %s> to current vertex <%s, %s>\n", $$origin_x, $$origin_y, $x, $y); } # /motion_xy =head2 stop_drawing_xy( $canvas, $x, $y, \$origin_x, \$origin_y ) =cut sub stop_drawing_xy { my $canvas = shift; my $x = shift; my $y = shift; my $origin_x = shift; my $origin_y = shift; $$origin_x = $x; $$origin_y = $y; $canvas->delete('line'); # -- Check if there is a valid target widget at <$x, $y>. If not, delete # the line && do nothing. my $w = $canvas->find("overlapping", $x, $y, $x+1, $y+1); print (defined $w ? "defined\n" : "undef\n"); return undef unless defined $w; #print Dumper($w); my $id = undef; WIDGETS: foreach my $widget ( @{$w} ) { my @tags = $canvas->itemcget($widget, '-tags'); next unless @tags; foreach my $tag ( @tags ) { if( $tag =~ m/^id\d+$/ ) { $id = $tag; last WIDGETS; } } } return undef unless $id; # there was no valid widget :-( print "target widget id = $id\n"; printf("stop drawing from vertex <%s, %s> to vertex <%s, %s>\n", $$origin_x, $$origin_y, $x, $y, ); } # /stop_drawing_xy http://www.intergastro-service.de (mein erstes CMS :) )
|