I am a quite beginner with tkinter. I am trying to visually connect two instances of some self created object on a canvas by clicking on them (right mouse click). In procedural coding style and using a global variable to count the clicks everything works fine. I cannot figure out what am I overlook in my code when I create everything in a class. Any clue?
from tkinter import Tk, Frame, Canvas, CURRENT, Text, END, TRUE, BOTH
class features_object():
def __init__(self, master, feature_text, feature_xpos, feature_ypos, feature_color):
self.master = master
self.feature_text = feature_text
self.feature_xpos = feature_xpos
self.feature_ypos = feature_ypos
self.feature_color = feature_color
self.click = 0
self.feature_frame = Frame(self.master, bg=self.feature_color, border=40)
self.feature_text = Text(self.feature_frame, font=("Helvetica", 12), relief='flat', width=20, height=3, selectbackground=self.feature_color, selectforeground="black", exportselection=TRUE)
self.feature_text.grid(row=0, column=0, padx=5, pady=5, sticky='w')
self.feature_text.config(wrap='word')
self.feature_text.insert(END, feature_text)
self.feature_tags = 'feature'
self.feature_id = self.master.create_window(self.feature_xpos, self.feature_ypos, window=self.feature_frame, tags=self.feature_tags)
self.bind_events()
def bind_events(self):
self.feature_frame.bind('<Button-1>', self.clicked)
self.feature_frame.bind('<Button-3>', self.draw_line_with_bind)
def clicked(self, event=None):
print(f'You clicked {self.feature_id} with the cords {self.master.coords(self.feature_id)}')
def draw_line_with_bind(self, event):
self.activ_elem = self.master.coords(self.feature_id)
if self.click == 0:
self.elem_start = self.activ_elem
self.start_x = self.activ_elem[0]
self.start_y = self.activ_elem[1]
self.click = 1
elif self.click == 1:
self.elem_end = self.activ_elem
self.end_x = self.activ_elem[0]
self.end_y = self.activ_elem[1]
self.master.create_line(self.start_x, self.start_y, self.end_x, self.end_y, fill="red", width=5)
self.click = 0
window = Tk()
window.geometry("1000x800")
frame_start = Frame(window)
frame_start.pack(expand=TRUE, fill=BOTH)
draw_canvas = Canvas(frame_start)
draw_canvas.pack(expand=TRUE, fill=BOTH)
created_feature_1 = features_object(draw_canvas, 'feature A', 100, 100, 'red')
created_feature_2 = features_object(draw_canvas, 'feature B', 300, 300, 'green')
created_feature_3 = features_object(draw_canvas, 'feature C', 500, 500, 'magenta')
if __name__ == '__main__':
window.mainloop()
CodePudding user response:
THis is happens because
self.start_x
,self.start_y
,self.end_x
,self.end_y
, andself.count
are not same for allfeatures_objects
instance.Means
self.start_x
,self.start_y
,self.end_x
,self.end_y
, andself.count
are different for allinstances
.You can use global here.
Try this.
from tkinter import Tk, Frame, Canvas, CURRENT, Text, END, TRUE, BOTH
click = 0
class features_object():
def __init__(self, master, feature_text, feature_xpos, feature_ypos, feature_color):
self.master = master
self.feature_text = feature_text
self.feature_xpos = feature_xpos
self.feature_ypos = feature_ypos
self.feature_color = feature_color
self.click = 0
self.feature_frame = Frame(self.master, bg=self.feature_color, border=40)
self.feature_text = Text(self.feature_frame, font=("Helvetica", 12), relief='flat', width=20, height=3, selectbackground=self.feature_color, selectforeground="black", exportselection=TRUE)
self.feature_text.grid(row=0, column=0, padx=5, pady=5, sticky='w')
self.feature_text.config(wrap='word')
self.feature_text.insert(END, feature_text)
self.feature_tags = 'feature'
self.feature_id = self.master.create_window(self.feature_xpos, self.feature_ypos, window=self.feature_frame, tags=self.feature_tags)
self.bind_events()
def bind_events(self):
self.feature_frame.bind('<Button-1>', self.clicked)
self.feature_frame.bind('<Button-3>', self.draw_line_with_bind)
def clicked(self, event=None):
print(f'You clicked {self.feature_id} with the cords {self.master.coords(self.feature_id)}')
def draw_line_with_bind(self, event):
global click,start_x,start_y,end_x,end_y
self.activ_elem = self.master.coords(self.feature_id)
if click == 0:
self.elem_start = self.activ_elem
start_x = self.activ_elem[0]
start_y = self.activ_elem[1]
click = 1
elif click == 1:
self.elem_end = self.activ_elem
end_x = self.activ_elem[0]
end_y = self.activ_elem[1]
self.master.create_line(start_x, start_y, end_x, end_y, fill="red", width=5)
print("asdkaj")
click = 0
window = Tk()
window.geometry("1000x800")
frame_start = Frame(window)
frame_start.pack(expand=TRUE, fill=BOTH)
draw_canvas = Canvas(frame_start)
draw_canvas.pack(expand=TRUE, fill=BOTH)
created_feature_1 = features_object(draw_canvas, 'feature A', 100, 100, 'red')
created_feature_2 = features_object(draw_canvas, 'feature B', 300, 300, 'green')
created_feature_3 = features_object(draw_canvas, 'feature C', 500, 500, 'magenta')
if __name__ == '__main__':
window.mainloop()
Output