[Tutor] Testing for mouse clicks

Alan Gauld alan.gauld at yahoo.co.uk
Sat Nov 7 19:47:31 EST 2020


On 07/11/2020 23:41, Phil wrote:
> Spurred on by success with my recent project involving a grid of lists, 

Sorry i dpn;t remember it. Which GUI toolkit are you using?
They are all very different!

> I now have another grid project in mind. If I want to test whether the 
> mouse is over, say one of six window locations, I would do something 
> like the following to test the mouse coordinates:
> 
> if 136 <= x <= 156 and 370 <= y <= 390:
>      do_something
> elif 186 <= x <= 206 and 370 <= y <= 390:
>      do_something
> elif 236 <= x <= 256 and 370 <= y <= 390:
>       do_something
> elif etc

See thats exactly what i would NOT do.
Its far too fragile, if any of those widgets changes size you
are in a mess. Better to express it in terms of the widgets
sizes. Especially if your grid has cells of equal size - at
least within a column or row. Then it becomes a matter of
(admittedly tedious) arithmetic rather than specifying each
location.

But that's rarely needed since most widgets have ways of detecting
if a mouse click happened. So in general when you create the grid
you can assign a mouse click handler to that cell. (You normally
only need a single handler for the whole grid, just assign
different x,y coordinates  in a lambda:

def mouseClickHandler(x,y):
    # handle it here using x,y

cell1 = Cell(....
             mouseclick = lambda x=0,y=0: mouseClickHandler(x,y)
             ...)
cell2 = Cell(....
             mouseclick = lambda x=0,y=1: mouseClickHandler(x,y)
             ...)
etc...

Now when the mouse is clicked in cell1 it calls mouseClickHandler(0,0)
and when the mouse is clicked in cell2 it calls mouseClickHandler(0,1)

So now you need to find out how/if your GUI toolkit binds mouseclicks to
cells. That will depend on the toolkit you are using and exactly what
kind of widget your cell consists of (Entry, Label,Canvas???).
For example in Tkinter you'd use the bind() method immediately after
creating the cell. Something like:

grid[x][y] = Label(gridFrame, text=....)
grid[x][y].bind("<Button-1>", lambda X=x, Y=y: mouseClickHandler(X,Y)
grid[x][y].grid(column=x,row=y,...)

> Now, if I have a 15 * 15 grid of window locations that I want to test 
> then repeating the above 225 times becomes a bit untidy, and tedious. 
> How might I best attack this mouse_testing problem?

If they are individual windows then your window widget almost
certainly allows binding of mouse events. You just need to find
out how.

Then it becomes a matter of 225 mouse bindings which is marginally easier.

But more likely you will create the grid using nested for loops
and the cell coordinates will be the loop variables. So it will
only be one line of code(as in the Tkinter example above).

But we can't be more specific without you showing us how you
create your cells and telling us which GUI toolkit you use.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list