Mrchooch
Mrchooch

Reputation: 211

Finding coordinates on a scrollable Tkinter canvas

I'm trying to make it so that when you right click, the row is highlighted blue and you can then edit or delete that entry. However, since adding a scrollbar, if the page is scrolled then the selection will be offset.

I have tried to suggested thing of finding the canvasx and canvasy and then using find_closest(0, however when i do that it always returns (1,) no matter what.

Canvasx and canvasy seem local to each label, not the canvas itself

from tkinter import *

def RightClick(event):
    #Find widgets on the row that was right clicked
    print(canvas.canvasy(event.y))
    for widget in frame.winfo_children():
        mouseClickY = event.y_root - root.winfo_y() - widget.winfo_height()
        widgetTopY = widget.winfo_y()
        widgetBottomY = widget.winfo_y() + widget.winfo_height()

        if (widget.winfo_class() == "Label") and (mouseClickY > widgetTopY) and (mouseClickY < widgetBottomY):
            #Highlight that row
            if widget.cget("bg") != "#338fff":
                widget.config(bg = "#338fff", fg="#FFFFFF")

        #Deselect all rows        
        elif widget.winfo_class() == "Label":
            widget.config(bg = "#FFFFFF", fg="#000000")

def onFrameConfigure(event):
    canvas.configure(scrollregion=canvas.bbox("all"))

root = Tk()
root.bind("<Button-3>", RightClick)

canvas = Canvas(root, width = 1080, height=500)
frame = Frame(canvas)  
scrollbar = Scrollbar(root, command=canvas.yview)
canvas.config(yscrollcommand=scrollbar.set) 

canvas.grid(row=1,column=0,columnspan=5)
canvas.create_window((0,0), window=frame, anchor="nw",tags="frame")
scrollbar.grid(column=5,row=1,sticky="NS")

frame.bind("<Configure>", onFrameConfigure)

for countY in range(40):
    for countX in range(6):
        l = Label(frame, text=countX, width = 25, height = 1, bg="#FFFFFF")
        l.grid(column=countX,row=countY+1)

Upvotes: 3

Views: 643

Answers (1)

Mrchooch
Mrchooch

Reputation: 211

Solved it, turns out

mouseClickY = event.y_root - root.winfo_y() - widget.winfo_height()
widgetTopY = widget.winfo_y()
widgetBottomY = widget.winfo_y() + widget.winfo_height()

should be

mouseClickY = event.y_root - root.winfo_y()
widgetTopY = widget.winfo_rooty()
widgetBottomY = widget.winfo_rooty() + widget.winfo_height()

OR

I should have used winfo_containing, which is a lot neater

Upvotes: 1

Related Questions