如何将列表框中的选定项值从一个模块返回到另一个模块?

问题描述 投票:0回答:1

我想将一个列表框中的选定项目从一个模块返回到另一个模块。在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()。这些都不起作用。

简而言之:如何分配“苹果”进行过滤?

python python-3.x tkinter listbox return
1个回答
1
投票

因此,这里的问题是,尽管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变量。

© www.soinside.com 2019 - 2024. All rights reserved.