PySimpleGUI中如何获取ListBox选中项在values列表的索引?
解决PySimpleGUI ListBox选中Event实例时获取原列表索引的问题
当ListBox中存在__str__输出相同的Event实例时,通过遍历列表或index()方法获取索引会失效——因为Pydantic模型默认按值比较,会匹配到第一个值相等的实例,而非实际选中的实例。以下是两种可行的解决方案:
方案1:直接访问底层tkinter组件获取选中索引
PySimpleGUI的ListBox封装了tkinter的Listbox控件,可直接调用底层方法获取选中项的索引:
修改后的完整代码:
from pydantic import BaseModel from datetime import datetime import PySimpleGUI as sg class Event(BaseModel): title: str moment: datetime description: str def __str__(self): return f"{self.title} at {str(self.moment)}" events_list = [ Event(title="test", moment=datetime(2023, 7, 2), description="hi"), Event(title="eger", moment=datetime(2023, 7, 4), description="34twerg"), # 添加测试用的重复内容实例 Event(title="test", moment=datetime(2023, 7, 2), description="another test"), ] event_select_tab = [ [sg.Text("event list editor")], [sg.Listbox(events_list, enable_events=True, key="-SELECT EVENT-", size=(25, 10))], [sg.Button("edit event", key="-EDIT EVENT-", enable_events=True)], ] layout = [[sg.TabGroup([[sg.Tab("events", event_select_tab)]])]] window = sg.Window("editor", layout) while True: event, values = window.read() if event == sg.WIN_CLOSED: break # 处理选中事件或编辑按钮点击 if event in ("-SELECT EVENT-", "-EDIT EVENT-"): selected_items = values["-SELECT EVENT-"] if selected_items: selected_event = selected_items[0] # 获取底层tkinter Listbox控件 listbox = window["-SELECT EVENT-"].Widget # 获取选中索引(curselection返回字符串元组,需转整数) selected_indices = listbox.curselection() if selected_indices: index = int(selected_indices[0]) print(f"选中项索引: {index},事件内容: {selected_event}") window.close()
方案2:为Event类添加唯一标识字段
给Event类增加一个唯一的id字段,创建实例时赋值唯一值,选中后通过匹配id确定索引:
修改后的核心代码:
class Event(BaseModel): id: int # 新增唯一标识字段 title: str moment: datetime description: str def __str__(self): return f"{self.title} at {str(self.moment)}" events_list = [ Event(id=1, title="test", moment=datetime(2023, 7, 2), description="hi"), Event(id=2, title="eger", moment=datetime(2023, 7, 4), description="34twerg"), Event(id=3, title="test", moment=datetime(2023, 7, 2), description="another test"), ] # 事件循环中获取索引部分 if event in ("-SELECT EVENT-", "-EDIT EVENT-"): selected_items = values["-SELECT EVENT-"] if selected_items: selected_event = selected_items[0] # 通过id匹配原列表索引 index = next(i for i, e in enumerate(events_list) if e.id == selected_event.id) print(f"选中项索引: {index},事件内容: {selected_event}")
内容的提问来源于stack exchange,提问作者ceayo
相关产品推荐
相关产品推荐

