如何在Kivy纯Python代码中实现鼠标选目录及on_selection事件疑问
解决Kivy FileChooser仅通过鼠标选择获取路径的问题
我来帮你理清这个问题的核心逻辑并给出解决方案,你遇到的on_selection绑定无效的情况,本质是对Kivy FileChooser的事件触发机制理解有偏差,下面详细说明:
一、on_selection事件的触发主体与逻辑
FileChooserListView的父类FileChooserBase是触发on_selection事件的类,但要明确两个关键点:
- 触发时机:用户点击选中某个文件/文件夹项时触发,而非进入目录的操作;
- 传递参数:事件会携带选中项的列表(
selection),而不是当前浏览目录的path属性。
你之前的绑定函数只接收了obj参数,没有处理selection,还错误地使用了self.fichoo.path,这就是绑定后无效果的原因。
二、两种需求对应的解决方案
根据你的描述,你可能有两种场景需求,对应不同的实现方式:
需求1:点击选中文件夹时,获取该文件夹的路径
修改绑定后的处理函数,接收selection参数并从中提取路径:
# 绑定事件无需修改,调整处理函数即可 self.fichoo.bind(on_selection = self.on_mouse_select) # 修正后的处理函数 def on_mouse_select(self, obj, selection): # selection是选中项的列表,单选场景下取第一个元素即可 if selection: self.tein_dir.text = str(selection[0])
需求2:进入目录(双击文件夹)时,自动获取当前目录路径
这种场景应该绑定on_path事件,因为path属性代表FileChooser当前浏览的目录,双击进入文件夹时path会更新并触发该事件:
# 替换原有的on_selection绑定为on_path self.fichoo.bind(on_path = self.on_dir_change) # 对应的处理函数 def on_dir_change(self, obj, new_path): self.tein_dir.text = str(new_path)
三、修正代码中的冗余问题
你的on_touch_up函数里写了两次return super().on_touch_up(touch),属于冗余代码;而且这个方法会在任何触摸抬起时触发,不管是不是操作了FileChooser,并不适合用来精准获取路径,建议移除或者修正。
修改后的完整示例代码
from kivy.uix.boxlayout import BoxLayout from kivy.uix.filechooser import FileChooserListView from kivy.uix.gridlayout import GridLayout from kivy.uix.label import Label from kivy.uix.textinput import TextInput from kivy.uix.button import Button class Explorer(BoxLayout): def __init__(self, **kwargs): super(Explorer,self).__init__(**kwargs) self.orientation = 'vertical' self.fichoo = FileChooserListView(size_hint_y = 0.8) self.add_widget(self.fichoo) control = GridLayout(cols = 5, row_force_default=True, row_default_height=35, size_hint_y = 0.14) lbl_dir = Label(text = 'Folder',size_hint_x = None, width = 80) self.tein_dir = TextInput(size_hint_x = None, width = 350) bt_dir = Button(text = 'Select Dir',size_hint_x = None, width = 80) bt_dir.bind(on_release =self.on_but_select) # 根据需求选择绑定事件:下面是需求2的on_path绑定 self.fichoo.bind(on_path = self.on_dir_change) # 如果是需求1,替换为:self.fichoo.bind(on_selection = self.on_mouse_select) control.add_widget(lbl_dir) control.add_widget(self.tein_dir) control.add_widget(bt_dir) self.add_widget(control) def on_but_select(self,obj): self.tein_dir.text = str(self.fichoo.path) def on_mouse_select(self, obj, selection): if selection: self.tein_dir.text = str(selection[0]) def on_dir_change(self, obj, new_path): self.tein_dir.text = str(new_path)
内容的提问来源于stack exchange,提问作者jasan
相关产品推荐
相关产品推荐

