So, the problem that I face and that I am trying to fix is the following. I am using the second part of the tkinter code from this guy (martineau) here: Selecting an area of an image with a mouse and recording the dimensions of the selection
I have taken the code and made it a callable class like this:
class select_area_class:
def __call__(self):
import tkinter as tk
from PIL import Image, ImageTk
WIDTH, HEIGHT = 900, 900
topx, topy, botx, boty = 0, 0, 0, 0
. . .
canvas.bind('<B1-Motion>', update_sel_rect)
window.mainloop()
The problem is that when this function is called:
def get_mouse_posn(event):
global topy, topx
topx, topy = event.x, event.y
. . .
(by the way I have erased this command: global topy, topx
because it was throwing me an error, so, I have made it like this:
def get_mouse_posn(event):
topx, topy = event.x, event.y
. . .
)
it does not update the main values: topx, topy
. So, anywhere I place the mouse inside the widget, I get as initial position the (0,0). I have tried to return event.x, event.y
but I cannot figure out how to read the return values from this command:
canvas.bind('<Button-1>', get_mouse_posn)
in order to update the main variables topx, topy
and so to make the code work.... I have read both how canvas work (here: https://web.archive.org/web/20201108093851id_/http://effbot.org/tkinterbook/canvas.htm) and how bind works (here: https://web.archive.org/web/20201111211515id_/https://effbot.org/tkinterbook/tkinter-events-and-bindings.htm ), but I cannot find a way to make it work. Any ideas?
CodePudding user response:
Since you have used class, it is better to use instance variables instead of global variables.
Also change get_mouse_posn()
and update_sel_rect()
to class methods as well.
Below is a simple example based on your posted code:
import tkinter as tk
from PIL import Image, ImageTk
class select_area_class:
def __call__(self):
window = tk.Tk()
WIDTH, HEIGHT = 900, 900
# use instance variables
self.topx, self.topy, self.botx, self.boty = 0, 0, 0, 0
self.canvas = tk.Canvas(window, width=WIDTH, height=HEIGHT)
self.canvas.pack()
self.canvas.bind('<Button-1>', self.get_mouse_posn)
self.canvas.bind('<B1-Motion>', self.update_sel_rect)
window.mainloop()
def get_mouse_posn(self, event):
self.topx, self.topy = self.botx, self.boty = event.x, event.y
self.rect_id = self.canvas.create_rectangle(self.topx, self.topy, self.botx, self.boty, outline='red')
def update_sel_rect(self, event):
self.botx, self.boty = event.x, event.y
self.canvas.coords(self.rect_id, self.topx, self.topy, self.botx, self.boty)
a = select_area_class()
a()
Note: Is it necessary to make the class callable?