Python 3.7 Treeview右键菜单获取选中项报错:'str'对象无'x'属性
解决Treeview右键菜单获取选中项的AttributeError问题
我来帮你排查这个错误~你遇到的AttributeError: 'str' object has no attribute 'x'是因为你给delete_selected传了一个字符串<Button-3>,而不是Tkinter的event对象,导致函数里试图访问event.x时出错。而且其实获取Treeview的选中项,根本不需要通过鼠标坐标来识别,用Treeview自带的方法更简单。
错误原因详解
你在添加右键菜单命令时写了:
self.popup_menu.add_command(label="stop process", command=lambda:self.delete_selected("<Button-3>"))
这里的lambda把字符串<Button-3>传给了delete_selected的event参数,而不是右键点击时产生的真实event对象。当delete_selected试图访问event.x时,字符串当然没有这个属性,所以报错。
修复方案
方案1:直接获取Treeview选中项(推荐)
Treeview有selection()方法,可以直接返回当前选中的所有项的ID列表,不需要依赖鼠标坐标。修改代码如下:
# 修改右键菜单命令,不需要传参数 self.popup_menu.add_command(label="stop process", command=self.delete_selected) self.tree.bind('<Button-3>', self.popup) def delete_selected(self): # 获取选中的项,返回的是列表,取第一个元素(如果是单选场景) selected_items = self.tree.selection() if selected_items: # 打印选中项的ID print("选中项ID:", selected_items[0]) # 如果要获取项的具体文本内容,比如第一个列的内容: item_text = self.tree.item(selected_items[0], 'values')[0] print("选中项内容:", item_text) def popup(self, event): """action in event of button 3 on tree view""" try: self.popup_menu.tk_popup(event.x_root, event.y_root, 0) finally: self.popup_menu.grab_release()
方案2:通过右键点击位置获取项(点击哪项操作哪项)
如果你想实现右键点击哪个项就操作哪个项(不管之前有没有选中),那需要把popup函数里的event传递给delete_selected:
self.tree.bind('<Button-3>', self.popup) def delete_selected(self, event): # 通过鼠标坐标识别点击的行ID item_id = self.tree.identify_row(event.y) if item_id: print("右键点击的项ID:", item_id) # 获取项的具体内容 item_text = self.tree.item(item_id, 'values')[0] print("右键点击的项内容:", item_text) def popup(self, event): """action in event of button 3 on tree view""" try: # 每次弹出菜单时重新绑定命令,传递当前的event self.popup_menu.delete(0, 'end') self.popup_menu.add_command(label="stop process", command=lambda e=event:self.delete_selected(e)) self.popup_menu.tk_popup(event.x_root, event.y_root, 0) finally: self.popup_menu.grab_release()
注意这个方案里,每次弹出菜单时需要重新添加命令,把当前的event传递进去,否则event会保留最后一次绑定的旧对象。
关键知识点
- Treeview的
selection()方法:返回当前选中的项ID列表,单选场景下取第一个元素即可。 - Treeview的
identify_row(y):通过鼠标的y坐标(相对于Treeview组件)识别点击的行ID。 - 右键菜单的command绑定:如果需要传递参数,要确保传递的是正确的对象(比如event),而不是字符串这类无关值。
内容的提问来源于stack exchange,提问作者programmer
相关产品推荐
相关产品推荐

