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

How to return a selected itemvalue from listbox from one module to another?

我想 return 从一个模块的列表框中 selected 项目到另一个模块。在 A.py 中,我从 B.py 调用了一个函数,它创建了一个小的 tkinter listbox。在这个列表框中,我想 select 一个项目,return 它作为 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 中获得了我想要的值,但我未能将其 return 分配给模块 A.py 并将其分配给 filter。我该怎么做?我在这里错过了什么?

我尝试了几种方法,包括 get_pt_filter 末尾的 return button_choose 或创建 Buttoncommand 后面的 lambda 函数。但是我无法打破循环,而且我似乎永远被困住了。我也尝试了 tk_window.mainloop()tk_window.wait_window()。 None 这些工作。

简而言之:如何将 "apple" 分配给过滤器?

所以这里的问题是,虽然 lb.get(lb.curselection()) 实际上计算为 "apple",但 button_click 无处可以 return 该值。您可以通过打印 button_click 函数而不是 returning 来验证这一点。为了尽可能多地使用您已经编写的代码,我建议您在 button_click 中创建一个全局变量,例如:

def button_click(lb):
    global selection
    selection = lb.get(lb.curselection())

然后您可以在 get_pt_filter 中访问变量 selection,从而从那里使用 return selection 访问变量 return。

要确保 'choose' 按钮实际关闭 window,您还应该将 'root' 设置为全局按钮:

global tk_window
tk_window = Tk()

并用 tk_window.quit() 完成 button_click,所以函数最终看起来像这样:

def button_click(lb):   
    global selection
    selection = lb.get(lb.curselection())
    tk_window.quit()

同时将 tk_window.wait_window() 替换为 tk_window.mainloop()

这是一个有点老套的解决方案,但它适合您已经编写的代码。

更好的解决方案 是将应用程序存储在 class 中,它有自己的变量,可以被 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 变量。