为什么Python tkinter按钮绑定的搜索函数无法正常筛选数据?
问题原因
- 核心问题是你创建了两个
Tk()主窗口实例,Tkinter的StringVar默认绑定到第一个创建的主窗口,导致搜索输入框绑定的q变量无法正确获取输入值,q.get()永远返回空字符串,SQL的LIKE '%%'就会匹配所有记录,所以永远展示全部数据。 - 次要问题:子窗口不应该用
Tk()创建,也不需要额外调用mainloop(),重复创建数据库连接和游标使用逻辑混乱,SQL语句的第二个模糊匹配条件缺少后缀通配符。
修复步骤
- 子窗口改用
Toplevel()创建,删除子窗口的mainloop()调用,全局只保留主窗口的一个mainloop() - 创建
StringVar时显式指定绑定的父窗口,确保输入值能正常获取 - 修正SQL语句的通配符,优化数据库连接逻辑避免重复连接
- 减少不必要的全局变量使用,优先用闭包内部变量传递组件和连接
修改后可运行代码
import tkinter as tk from tkinter import ttk, Toplevel import sqlite3 menu = tk.Tk() def search(): # 复用同一个数据库连接,不需要重复创建 conn = sqlite3.connect('ksiazka.db') k = conn.cursor() # 子窗口用Toplevel而不是Tk wyszukaj = Toplevel(menu) # 显式指定StringVar的master为子窗口,保证变量绑定正确 q = tk.StringVar(master=wyszukaj) def update_new(rows): trv.delete(*trv.get_children()) for i in rows: trv.insert('', 'end', values=i) conn.commit() def sercz(): q2 = q.get() # 修正nazwisko的模糊匹配通配符,前后都加%实现全字段模糊搜索 query = f"SELECT *, oid FROM pracownicy WHERE imie LIKE '%{q2}%' OR nazwisko LIKE '%{q2}%'" k.execute(query) rows = k.fetchall() update_new(rows) wrapper1 = tk.LabelFrame(wyszukaj,text="Pracownicy") wrapper2 = tk.LabelFrame(wyszukaj,text="Wyszukaj Pracownika") wrapper1.pack(fill="both", expand="yes",padx=20,pady=10) wrapper2.pack(fill="both",expand="yes",padx=20,pady=10) trv = ttk.Treeview(wrapper1, columns=(1,2,3,4,5,6),show="headings",height="6") trv.pack() # 此处列头可根据你的实际字段修改,原代码所有列头都写为customerid仅做保留 trv.heading(1,text="customerid") trv.heading(2, text="customerid") trv.heading(3, text="customerid") trv.heading(4, text="customerid") trv.heading(5, text="customerid") trv.heading(6, text="customerid") query = "SELECT *,oid FROM pracownicy" k.execute(query) rows = k.fetchall() update_new(rows) # 搜索区域组件 lbl = tk.Label(wrapper2,text="Search") lbl.pack(side=tk.LEFT,padx=10) ent = tk.Entry(wrapper2,textvariable=q) ent.pack(side=tk.LEFT,padx=6) butter = tk.Button(wrapper2,text="Search",command=sercz) butter.pack(side=tk.LEFT,padx=6) wyszukaj.title("MyAPP") wyszukaj.geometry("800x700") search_btn1 = tk.Button(menu,text="Wyszukaj pracownika",command=search) search_btn1.grid(row=12,column=0) menu.geometry("500x500") menu.mainloop()
注意事项
- 上述代码用f字符串拼接SQL仅为和原逻辑对齐,正式使用建议改用参数化查询避免SQL注入风险,写法如下:
query = "SELECT *, oid FROM pracownicy WHERE imie LIKE ? OR nazwisko LIKE ?" k.execute(query, (f'%{q2}%', f'%{q2}%'))
内容的提问来源于stack exchange,提问作者zz w0jt3k
相关产品推荐
相关产品推荐

