如何基于搜索查询对Gtk.ListBox中的行进行排序?
Gtk.ListBox 基于搜索查询排序的set_sort_func()示例
下面是一个完整的PyGObject示例,展示如何结合搜索框和set_sort_func()实现动态排序:
import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk class SortableListBoxWindow(Gtk.Window): def __init__(self): super().__init__(title="搜索排序示例") self.set_default_size(300, 400) # 创建垂直布局容器 box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) self.add(box) # 添加搜索框 self.search_entry = Gtk.Entry() self.search_entry.set_placeholder_text("输入关键词搜索...") # 搜索文本变化时触发重新排序 self.search_entry.connect("changed", self.on_search_changed) box.pack_start(self.search_entry, False, False, 0) # 创建ListBox self.listbox = Gtk.ListBox() self.listbox.set_selection_mode(Gtk.SelectionMode.SINGLE) box.pack_start(self.listbox, True, True, 0) # 初始化列表数据 items = [ "苹果", "香蕉", "橙子", "葡萄", "西瓜", "草莓", "蓝莓", "猕猴桃", "芒果", "菠萝" ] for item in items: row = Gtk.ListBoxRow() label = Gtk.Label(label=item) row.add(label) self.listbox.add(row) # 设置排序函数 self.listbox.set_sort_func(self.sort_rows) def sort_rows(self, row1, row2): # 获取两行的文本内容 label1 = row1.get_child() label2 = row2.get_child() text1 = label1.get_text().lower() text2 = label2.get_text().lower() search_text = self.search_entry.get_text().lower() # 核心排序逻辑:优先把包含搜索词的项排前面 match1 = search_text in text1 match2 = search_text in text2 if match1 and not match2: return -1 # row1排前面 elif not match1 and match2: return 1 # row2排前面 else: # 都匹配或都不匹配时,按字母顺序排序 if text1 < text2: return -1 elif text1 > text2: return 1 else: return 0 def on_search_changed(self, entry): # 触发列表重新排序 self.listbox.invalidate_sort() win = SortableListBoxWindow() win.connect("destroy", Gtk.main_quit) win.show_all() Gtk.main()
关键细节说明:
- 排序函数规则:
set_sort_func()传入的函数需接收两个Gtk.ListBoxRow参数,返回值规则:- 返回-1:row1排在row2前面
- 返回1:row2排在row1前面
- 返回0:两行顺序不变
- 动态触发排序:搜索框文本变化时,调用
listbox.invalidate_sort(),GTK会自动调用自定义排序函数重新排列行。 - 自定义排序逻辑:示例中先按是否包含搜索词分组,再按字母排序,你可根据需求修改,比如按前缀匹配优先级、字符串长度等规则调整。
- 行内容提取:通过
row.get_child()获取行内控件(示例中是Label),再提取文本进行比较。
内容的提问来源于stack exchange,提问作者user_968563
相关产品推荐
相关产品推荐

