Как вернуть выбранное значение элемента из списка из одного модуля в другой? - PullRequest
0 голосов
/ 25 марта 2020

Я хочу вернуть выбранный элемент из списка из одного модуля в другой. Внутри 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. Я не могу сломать L oop, однако, и я застрял навсегда, как кажется. Также я попробовал tk_window.mainloop() и tk_window.wait_window(). Ничего из этого не работает.

Короче говоря : Как назначить «яблоко» для фильтрации?

1 Ответ

1 голос
/ 25 марта 2020

Таким образом, проблема в том, что хотя 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.

Чтобы убедиться, что кнопка «на самом деле» закрывает окно, вы также должны сделать глобальным «root»:

global tk_window
tk_window = Tk()

и fini sh 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. Посмотрите на эту тему . Я предлагаю следующее приложение для выполнения sh того, что вам нужно без использования 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 varaible экземпляра.

...