我想将一个列表框中的选定项目从一个模块返回到另一个模块。在A.py
内部,我从B.py
调用了一个函数,该函数创建了一个小tkinter listbox
。我要在此列表框中选择一个项目,并将其作为值返回到A.py
。
我尝试了几件事,例如
# inside A.py
import B
filter = B.get_pt_filter()
和
# inside B.py
from tkinter import * # (i know this is not clean, but let's keep it this way for now)
from functools import partial
def button_click(lb):
return lb.get(lb.curselection())
def get_pt_filter():
pt_list = define_pt_list()
# create window
tk_window = Tk()
tk_window.title('Choose')
tk_window.geometry('350x400')
# listbox border
frame_listbox = Frame(master=tk_window, bg='#FFCFC9')
frame_listbox.place(x=5, y=5, width=335, height=360)
# button border
frame_button = Frame(master=tk_window, bg='#D5E88F')
frame_button.place(x=5, y=370, width=335, height=30)
# Listbox
lb = Listbox(master=frame_listbox, selectmode='browse')
for pt in pt_list:
lb.insert('end', pt)
lb.place(x=5, y=5, width=325, height=350)
# Label Text
labelText = Label(master=frame_button, bg='white')
labelText.place(x=5, y=5, width=325, height=20)
# button_choose = Button(master=frame_button, text='Choose', command= lambda: button_click(lb))
action_with_arg = partial(button_click, lb)
button_choose = Button(master=frame_button, text='Choose', command=action_with_arg)
button_choose .place(x=5, y=5, width=325, height=20)
# Aktivierung des Fensters
tk_window.wait_window()
def define_pt_list():
return [
'apple'
]
到目前为止,我在button_click
中得到了我想要的值,但是我未能将其返回到模块A.py
并将其分配给filter
。我该怎么办?我在这里想念什么?
我已经尝试了几件事,包括在创建return button_choose
时在get_pt_filter
末尾的command
或在Button
后面的lambda函数。但是,我无法打破循环,而且似乎永远被卡住。我也尝试了tk_window.mainloop()
和tk_window.wait_window()
。这些都不起作用。
简而言之:如何分配“苹果”进行过滤?
因此,这里的问题是,尽管lb.get(lb.curselection())
实际上求值为"apple"
,但button_click
无处可返回该值。您可以通过打印button_click
功能而不是返回来验证这一点。为了使用您已经编写的代码,我建议您在button_click
中创建一个全局变量,例如:
def button_click(lb):
global selection
selection = lb.get(lb.curselection())
然后,您可以访问selection
中的变量get_pt_filter
,并由此通过return selection
从那里返回它。
为了确保“选择”按钮实际上关闭了窗口,您还应该将“根”设置为全局:
global tk_window
tk_window = Tk()
并用button_click
结束tk_window.quit()
的,所以函数最终看起来像这样:
def button_click(lb):
global selection
selection = lb.get(lb.curselection())
tk_window.quit()
也用tk_window.wait_window()
替换tk_window.mainloop()
。
这有点棘手,但是适合您已经编写的代码。
[一种更好的解决方案将应用程序存储在一个类中,该类具有自己的变量,可以由button_click
访问。看看this thread。我建议以下应用程序无需使用global
即可完成所需的工作:
from tkinter import *
class get_pt_filter:
def __init__(self, parent, pt_list):
# create window
self.tk_window = parent
self.tk_window.title('Choose')
self.tk_window.geometry('350x400')
# listbox border
frame_listbox = Frame(master=self.tk_window, bg='#FFCFC9')
frame_listbox.place(x=5, y=5, width=335, height=360)
# button border
frame_button = Frame(master=self.tk_window, bg='#D5E88F')
frame_button.place(x=5, y=370, width=335, height=30)
# Listbox
self.lb = Listbox(master=frame_listbox, selectmode='browse')
for pt in pt_list:
self.lb.insert('end', pt)
self.lb.place(x=5, y=5, width=325, height=350)
# Label Text
labelText = Label(master=frame_button, bg='white')
labelText.place(x=5, y=5, width=325, height=20)
button_choose = Button(master=frame_button, text='Choose', command=self.button_click)
button_choose.place(x=5, y=5, width=325, height=20)
def button_click(self):
self.selection = self.lb.get(self.lb.curselection())
self.tk_window.quit()
if __name__ == "__main__":
parent = Tk()
get = get_pt_filter(parent, ['apple', 'pear'])
# Aktivierung des Fensters
parent.mainloop()
#access the selection
print(get.selection)
mainloop
退出时,您可以访问实例的selection
变量。