如何获取Tkinter循环创建的create_text对应文本?itemcget仅返回最后值
问题解决方法
问题出在循环中title变量被反复覆盖,导致on_press_edit始终访问最后一次循环生成的文本项ID,而非当前点击的画布对应的标题。以下是两种可行的解决方式:
方法一:给画布绑定专属属性存储标题ID
修改循环内的代码,将每个画布对应的标题ID存为画布的属性,在点击事件中通过事件对象获取当前画布,再读取其属性:
def on_press_edit(e): # 获取当前点击的画布,再读取它存储的标题ID current_canvas = e.widget title_get = current_canvas.itemcget(current_canvas.title_id, 'text') for cells in range(2, ea.max_row + 1): if title_get == ea['A' + str(cells)].value: print(title_get) for added_notes in range(2, ea.max_row + 1): seperation = (added_notes * 90) - 120 value = ea['A' + str(added_notes)].value cell_text = ea['B' + str(added_notes)].value text_display = cell_text[:20] note_canvas = Canvas(canvas, height=80, width=315, bg='#FBADB1') title = note_canvas.create_text(10, 22, text=value, anchor='w', font=('San Francisco', 14, 'bold')) # 将标题ID存为当前画布的属性 note_canvas.title_id = title note_canvas.create_text(10, 45, text=text_display + '...', anchor='w', font=('San Francisco', 10)) note_canvas.bind('<Button-1>', on_press_edit) window = canvas.create_window(165, seperation, window=note_canvas) canvas.update_idletasks() canvas.config(scrollregion=canvas.bbox("all")) vbar.set(0, 1)
方法二:通过lambda传递参数
在绑定事件时,直接将当前画布和标题ID作为参数传递给事件处理函数:
def on_press_edit(e, note_canvas, title): title_get = note_canvas.itemcget(title, 'text') for cells in range(2, ea.max_row + 1): if title_get == ea['A' + str(cells)].value: print(title_get) for added_notes in range(2, ea.max_row + 1): seperation = (added_notes * 90) - 120 value = ea['A' + str(added_notes)].value cell_text = ea['B' + str(added_notes)].value text_display = cell_text[:20] note_canvas = Canvas(canvas, height=80, width=315, bg='#FBADB1') title = note_canvas.create_text(10, 22, text=value, anchor='w', font=('San Francisco', 14, 'bold')) note_canvas.create_text(10, 45, text=text_display + '...', anchor='w', font=('San Francisco', 10)) # 使用lambda传递当前画布和标题ID note_canvas.bind('<Button-1>', lambda e, nc=note_canvas, t=title: on_press_edit(e, nc, t)) window = canvas.create_window(165, seperation, window=note_canvas) canvas.update_idletasks() canvas.config(scrollregion=canvas.bbox("all")) vbar.set(0, 1)
原理说明
循环中每次生成的note_canvas和title都是独立的,但原代码中事件处理函数没有绑定当前迭代的变量,而是引用了循环结束后最终的变量值。通过上述两种方式,能确保点击事件关联的是当前画布对应的标题ID,从而正确获取点击项的文本内容。
内容的提问来源于stack exchange,提问作者aka_gail
相关产品推荐
相关产品推荐

