Discussion:
Generate <Shift-Button> event on a canvas (on Windows)
(too old to reply)
Helmut Giese
2024-08-05 15:27:31 UTC
Permalink
Hello out there,
I am writing tests (using tcltest) to avoid any regression during
development but I hit something like a brick wall: 'event generate'
appears not to work on items of a canvas. On regular widgets no
problem: It can produce events like <Button-1>, <Shift-Button-1> ,
etc.
With twapi on the other hand I can produce <Button-1> events
everywhere: canvas, widgets - but no <Shift-Button-1>, so I'm stuck.
So the question is: How to make 'event generate' work on canvas items
or how to tweak twapi to also produce <Shift-Button> events.
Any help will be greatly apppreciated
Helmut
PS: I am running Tcl 8.6.10 under Windows 10, 64 bit
Helmut Giese
2024-08-06 12:10:30 UTC
Permalink
To answer my own question: The following script does the trick.
---
package require Tk
foreach ch [winfo children .] {destroy $ch}

set fr [ttk::frame .fr]
set btn1 [ttk::button $fr.btn1 -text "Simple click"]
set btn2 [ttk::button $fr.btn2 -text "Shift click"]
pack $btn1 $btn2
pack $fr

bind $btn1 <Button-1> {puts "Simple click"}
bind $btn2 <Shift-Button-1> {puts "Shift click"}

puts -nonewline "Press <Enter> to watch a message appear ... "
gets stdin
event generate $btn1 <Button-1>
puts -nonewline "Press <Enter> to watch another message appear ... "
gets stdin
event generate $btn2 <Button-1> -state 31
---
The trick is the '-state 31' to achieve a 'Shift click'. I discovered
this flag / option on the event manual page where it was mentioned
that it 'Corresponds to the %s substitution for binding scripts.'
Then it was only a matter of trying out what a 'Shift click' produced
with '%s'.

I hope this will be useful to some of you some time ...
Helmut
Helmut Giese
2024-08-06 12:31:50 UTC
Permalink
Well the joy was premature: It works with e.g. buttons but not with
canvas items. And I believre now that it cannot be done:
The 'event generate' command expects a window - in this case the
canvas - and delivers the event there. So I do not see a chance to
deliver different events to individual items on this canvas.
Too bad ...
Schelte
2024-08-06 13:51:42 UTC
Permalink
Post by Helmut Giese
Well the joy was premature: It works with e.g. buttons but not with
The 'event generate' command expects a window - in this case the
canvas - and delivers the event there. So I do not see a chance to
deliver different events to individual items on this canvas.
Too bad ...
You have to provide an x- and y coordinate for the canvas to be able to
determine which item is affected:

canvas .c -width 500 -height 500
set sq1 [.c create rectangle 100 100 200 200 -fill blue]
set sq2 [.c create rectangle 300 300 400 400 -fill red]
pack .c
.c bind $sq1 <1> {puts "Square 1"}
.c bind $sq2 <1> {puts "Square 2"}
after 1000 {event generate .c <Button-1> -x 120 -y 180}
after 2000 {event generate .c <Button-1> -x 320 -y 380}

The coordinates will have to be adjusted if the canvas is scrolled.


Schelte
Helmut Giese
2024-08-06 20:21:49 UTC
Permalink
Schlau müsste man sein ... (Appr. translation: It would help to be
smart ...)
Hi Schelte,
it works - of course it does.
I read the event man page over and over, up and down. I was even a
little proud to have found the '-state' option which helped with my
'shift click' problem. Of course I read the section with the -x and -y
options but it never occurred to me to make a connection:
- I want to generate an event on a canvas.
- I have different items there and I want to direct the event to a
particular item.
And no, it didn't occur to me that using the item's coordinates could
help with that. As I said above: Schlau müsste man sein ...

Many, many thanks Schelte. I'm so grateful for all you smart and
helpful guys hanging around here.
Helmut

Loading...