@@ -444,19 +444,40 @@ def _open_column_filter(self, tk_col: str, x_root: Optional[int] = None, y_root:
444444 if x_root is not None and y_root is not None :
445445 d .geometry (f"+{ x_root - 8 } +{ y_root + 8 } " )
446446
447+ search_var = tk .StringVar ()
448+ shown : List [str ] = []
449+ current = self ._active_filters .get (col )
450+
451+ ttk .Label (d , text = "搜索:" ).grid (row = 0 , column = 0 , padx = (8 , 4 ), pady = (8 , 4 ), sticky = tk .W )
452+ search_ent = ttk .Entry (d , textvariable = search_var , width = 28 )
453+ search_ent .grid (row = 0 , column = 1 , columnspan = 2 , padx = (0 , 8 ), pady = (8 , 4 ), sticky = "ew" )
454+
447455 lst = tk .Listbox (d , selectmode = tk .MULTIPLE , width = 36 , height = 12 )
448- lst .grid (row = 0 , column = 0 , columnspan = 3 , padx = 8 , pady = (8 , 6 ), sticky = "nsew" )
449- for item in values :
450- lst .insert (tk .END , item if item else "(空)" )
456+ lst .grid (row = 1 , column = 0 , columnspan = 3 , padx = 8 , pady = (0 , 6 ), sticky = "nsew" )
451457
452- current = self ._active_filters .get (col )
453- if current :
454- for i , v in enumerate (values ):
455- if v in current :
458+ def repopulate (* _ , init : bool = False ) -> None :
459+ nonlocal shown
460+ if init :
461+ prev_selected = set (current ) if current else set ()
462+ else :
463+ prev_selected = {shown [i ] for i in lst .curselection ()} if shown else set ()
464+ q = search_var .get ().strip ().lower ()
465+ if q :
466+ shown = [v for v in values if q in (v or "" ).lower ()]
467+ else :
468+ shown = list (values )
469+ lst .delete (0 , tk .END )
470+ for v in shown :
471+ lst .insert (tk .END , v if v else "(空)" )
472+ for i , v in enumerate (shown ):
473+ if v in prev_selected :
456474 lst .select_set (i )
457475
476+ search_var .trace_add ("write" , lambda * _ : repopulate (init = False ))
477+ repopulate (init = True )
478+
458479 def apply_filter () -> None :
459- selected = {values [i ] for i in lst .curselection ()}
480+ selected = {shown [i ] for i in lst .curselection ()}
460481 if selected :
461482 self ._active_filters [col ] = selected
462483 else :
@@ -471,11 +492,12 @@ def clear_filter() -> None:
471492 self ._rebuild_tree ()
472493 d .destroy ()
473494
474- ttk .Button (d , text = "应用筛选" , command = apply_filter ).grid (row = 1 , column = 0 , padx = 8 , pady = (0 , 8 ), sticky = "w" )
475- ttk .Button (d , text = "清除此列" , command = clear_filter ).grid (row = 1 , column = 1 , padx = 4 , pady = (0 , 8 ))
476- ttk .Button (d , text = "取消" , command = d .destroy ).grid (row = 1 , column = 2 , padx = 8 , pady = (0 , 8 ), sticky = "e" )
477- d .rowconfigure (0 , weight = 1 )
495+ ttk .Button (d , text = "应用筛选" , command = apply_filter ).grid (row = 2 , column = 0 , padx = 8 , pady = (0 , 8 ), sticky = "w" )
496+ ttk .Button (d , text = "清除此列" , command = clear_filter ).grid (row = 2 , column = 1 , padx = 4 , pady = (0 , 8 ))
497+ ttk .Button (d , text = "取消" , command = d .destroy ).grid (row = 2 , column = 2 , padx = 8 , pady = (0 , 8 ), sticky = "e" )
498+ d .rowconfigure (1 , weight = 1 )
478499 d .columnconfigure (0 , weight = 1 )
500+ d .columnconfigure (1 , weight = 1 )
479501 d .columnconfigure (2 , weight = 1 )
480502
481503 def refresh_sessions (self , sessions : List ["ClientSession" ]) -> None :
0 commit comments