Python tkinter列表框未使用跟踪()更新
基本上,我试图在tkinter中创建一个搜索框,您可以在其中尝试输入框中的内容,并在下面的列表框中显示包含您键入内容的特定列表中的所有内容。我从你那里得到了初始代码 但是,由于我不太了解课程,我决定将其缩短为:Python tkinter列表框未使用跟踪()更新,python,tkinter,Python,Tkinter,基本上,我试图在tkinter中创建一个搜索框,您可以在其中尝试输入框中的内容,并在下面的列表框中显示包含您键入内容的特定列表中的所有内容。我从你那里得到了初始代码 但是,由于我不太了解课程,我决定将其缩短为: from tkinter import * root = Tk() def update_list(*args): search_term = search_var.get() # Just a generic list to populate the listbo
from tkinter import *
root = Tk()
def update_list(*args):
search_term = search_var.get()
# Just a generic list to populate the listbox
lbox_list = ['Adam', 'Lucy', 'Barry', 'Bob',
'James', 'Frank', 'Susan', 'Amanda', 'Christie']
lbox.delete(0, END)
for item in lbox_list:
if search_term.lower() in item.lower():
lbox.insert(END, item)
# searchbar
search_var = StringVar()
search_var.trace("w", update_list)
entry = Entry(root,textvariable=search_var, width=13)
lbox = Listbox(root, width=45, height=15)
entry.grid(row=1, column=0, padx=2, pady=3)
lbox.grid(row=2, column=0, rowspan=20, padx=2, pady=3)
update_list()
root.mainloop()
这段代码运行得很好,所以我决定将它应用到我的实际程序中,这就是我遇到问题的地方
def main():
# searchbar
search_var = StringVar()
entry = Entry(root,textvariable=search_var, width=13)
lbox = Listbox(root, width=40, height=15)
entry.grid(row=1, column=0, padx=2, pady=3)
lbox.grid(row=2, column=0, padx=2, pady=3)
search_var.trace("w", update_list)
update_list(search_var,lbox)
def update_list(search_var,lbox):
search_term = search_var.get()
print(search_term)
# Just a generic list to populate the listbox
lbox_list = ['Adam', 'Lucy', 'Barry', 'Bob',
'James', 'Frank', 'Susan', 'Amanda', 'Christie']
lbox.delete(0, END)
for item in lbox_list:
if search_term.lower() in item.lower():
lbox.insert(END, item)
# main window (menu)
root = Tk()
main()
root.mainloop()
我遇到的问题是列表框不更新。任何帮助都将不胜感激。您的问题是,
search\u var
在main
函数完成时过期,因此,您告诉它执行的任何更新也将过期。@acw1668解决方案之所以有效,是因为lambda
使引用保持活动状态。这也可以通过global
关键字来实现,尽管我更喜欢acw1668的方法,因为它提供了少量的封装。然而,滥用lambda
仅仅为了保持任意引用的活跃性并不是一个好的设计选择。另外,如果在循环中使用多个重复引用执行此操作,因为lambda
当前处于状态,则只有最后一个引用将保持活动状态
这就是全球方法的样子
from tkinter import *
root = Tk()
def main():
global search_var
search_var = StringVar()
entry = Entry(root, textvariable=search_var, width=13)
entry.grid(padx=2, pady=3)
global lbox
lbox = Listbox(root, width=40, height=15)
lbox.grid(padx=2, pady=3)
search_var.trace("w", update_list)
update_list(lbox)
def update_list(*args):
search_term = search_var.get()
lbox_list = ['Adam', 'Lucy', 'Barry', 'Bob',
'James', 'Frank', 'Susan', 'Amanda', 'Christie']
lbox.delete(0, END)
for item in lbox_list:
if search_term.lower() in item.lower():
lbox.insert(END, item)
main()
root.mainloop()
我注意到你说你这样做是因为你需要在将来再次得到这个显示器。这意味着您打算在某个时候取消此显示。当你没有引用任何你刚刚制作的小部件时,你打算怎么做?您的设计存在很大缺陷,而且lambda
无法帮助您改进。也许你想考虑一个设计,实际上给你一点点的控制。
import tkinter as tk
root = tk.Tk()
def search_frame(row=0, column=0):
frame = tk.Frame(root)
frame.grid(row=row, column=column)
def update_list(*args):
search_term = entry.var.get()
lbox_list = ['Adam', 'Lucy', 'Barry', 'Bob',
'James', 'Frank', 'Susan', 'Amanda', 'Christie']
lbox.delete(0, tk.END)
for item in lbox_list:
if search_term.lower() in item.lower():
lbox.insert(tk.END, item)
entry = tk.Entry(frame, width=13)
entry.var = tk.StringVar()
entry.var.trace("w", update_list)
entry.configure(textvariable=entry.var)
entry.grid(padx=2, pady=3)
lbox = tk.Listbox(frame, width=40, height=15)
lbox.grid(padx=2, pady=3)
update_list()
return frame
searchframe = search_frame()
root.mainloop()
两者有什么区别?您给它起了一个名为
main
,它只会被调用一次。你使它比第一次更复杂one@Karthik我需要能够在将来再次执行main()的内容,这就是我将其作为函数的原因。问题源于在函数中创建搜索栏,但是我不知道为什么,也不知道如何修复它,因为我需要在函数中使用它。请尝试将search\u var.trace(“w”,update\u list)
更改为search\u var.trace(“w”,lambda*args:update\u list(search\u var,lbox))
@acw1668谢谢您的完美工作!介意解释一下它是如何工作的或者链接一个这样的网站吗?我想很可能search\u var
是main()
函数中的一个局部变量。因此,使用search\u var.trace(“w”,update\u list)
并不明确表示search\u var
在main()
返回后被引用,它可能被垃圾收集。但是,使用search\u var.trace(“w”,lambda*args:update\u list(search\u var,lbox))
明确显示search\u var
在main()
返回后仍会被引用。感谢您提供的详细答案。我在main()的开头使用root.winfo_children():widget.destroy()``中的widget来刷新它,而不是去掉显示,然后重新构建它。这是因为根据用户的操作,根窗口将被更改。我确实考虑过这一点,但我最初的实现是search\u var.trace(“w”,lambda search\u var,lbox:update\u list(search\u var,lbox))
,但我无法获得正确的输出,所以我像nvm一样,但是*args
起到了作用。@Friend\u Slayer666~看看我在答案底部附加了什么。直到你可以在函数中定义函数为止。我非常喜欢你的代码。感谢您的帮助:)@Friend\u Slayer666~关于“我非常喜欢您的代码”。谢谢,但不是很好。所有这些程序编程的东西都是一团糟。如果我为自己写这篇文章,defsearch\u frame
将是classsearchframe
。它将是非常通用、动态和可重用的,我再也不用写它了,但我可以在任何地方使用它。就像您使用条目
,标签
等一样。。什么都可以。