【问题标题】:How to return a list from an event function in tkinter?如何从 tkinter 中的事件函数返回列表?
【发布时间】:2020-08-16 03:48:32
【问题描述】:

我正在尝试了解如何从用户使用鼠标键将左侧框中的项目移动到右侧框时使用的函数返回列表。我正在尝试将右侧框中的项目捕获为列表,但在函数之外需要该列表。

所以我试图从 select_events 函数返回列表 (current_list)。它正在捕获函数中的列表,但我需要在外面使用它。我很难理解如何使用return 来做到这一点

from tkinter import *
from tkinter import ttk

my_window = Tk()

my_frame_in = Frame(my_window)
my_frame_in.grid(row=0, column=0)
my_frame_out = Frame(my_window)
my_frame_out.grid(row=0, column=1)

listbox_events = Listbox(my_frame_in, height='5')
listbox_events.grid(row=0, column=0, padx=10, pady=10)
listbox_events_filtered = Listbox(my_frame_out, height='5')
listbox_events_filtered.grid(row=0, column=2, padx=(0, 10), pady=10)
my_instructions = Label(my_window, text='Use arrow keys to move selected items')
my_instructions.grid(row=1, column=0, columnspan=3, pady=(0, 10))

my_list_events = ['A', 'B', 'C', 'D']

for item in my_list_events:
    listbox_events.insert(END, item)

global current_list


def select_events(event=None):
#    current_list = []
    listbox_events_filtered.insert(END, listbox_events.get(ANCHOR))
    listbox_events.delete(ANCHOR)
    current_list = list(listbox_events_filtered.get(0, END))
    print(current_list)
    return current_list


print(current_list)


def deselect_events(event=None):
#    current_list = []
    listbox_events.insert(END, listbox_events_filtered.get(ANCHOR))
    listbox_events_filtered.delete(ANCHOR)
    current_list = list(listbox_events_filtered.get(0, END))


listbox_events.bind('<Right>', select_events)
listbox_events_filtered.bind('<Left>', deselect_events)

mainloop()

【问题讨论】:

  • 将列表返回给哪个调用者?
  • 我不明白你的意思?我显然做错了。 current_list 中的项目将构成文件名的一部分,稍后将在代码中使用下面的行使用该文件名。但目前我不能从函数中传递任何东西。我稍后将在代码中使用下面的行来读取 current_list 中的项目以获取 current_list 中的项目: x, y = np.loadtxt(item + '_' + 'Test.csv', skiprows=1, usecols=[my_col_x_axis , my_col_y_axis], unpack=True, delimiter=',')
  • 事件处理程序通常由tkinter 调用,而不是直接调用,它会忽略它们的返回值——这就是我问的原因。虽然使用全局变量通常不是一个好主意,但您可以select_events() 函数定义的开头声明global current_list,然后能够创建和更新其值。你目前拥有global current_list 语句的地方什么都不做。
  • 我建议你看看问题Best way to structure a tkinter application? 的答案,以了解如何避免在 tkinter 应用程序中使用全局变量。
  • 谢谢 - 那么我是否在 select_event 函数的末尾正确使用了 return current_list 语句。?下面的 print(current_list) 语句没有返回任何内容,所以不要认为我有权利

标签: python list tkinter event-handling


【解决方案1】:

这里有一些说明可以做什么,因为没有有意义的方法可以从tkinter 事件处理函数返回值。它展示了如何引用像current_list 这样的全局变量,以便在inside 函数中使用(即通过将其声明为global)。

您只需要在函数尝试更改值时这样做——该语句告诉 Python not 在分配某些东西时创建一个具有该名称的局部变量它(这是默认行为)。

我添加了一个 Process current list Button 到 GUI 中,该 GUI 将调用一个函数,该函数还会在单击时添加名为 process_list() 的函数。此函数包含您在其中一个 cmets 中提到的(已注释掉的)代码,以指示可以在何处进行此类处理。

from tkinter import *
from tkinter import ttk

my_window = Tk()

my_frame_in = Frame(my_window)
my_frame_in.grid(row=0, column=0)
my_frame_out = Frame(my_window)
my_frame_out.grid(row=0, column=1)

listbox_events = Listbox(my_frame_in, height='5')
listbox_events.grid(row=0, column=0, padx=10, pady=10)
listbox_events_filtered = Listbox(my_frame_out, height='5')
listbox_events_filtered.grid(row=0, column=2, padx=(0, 10), pady=10)
my_instructions = Label(my_window, text='Use arrow keys to move selected items')
my_instructions.grid(row=1, column=0, columnspan=3, pady=(0, 10))

my_list_events = ['A', 'B', 'C', 'D']
current_list = []  # Initilize global variable.

for item in my_list_events:
    listbox_events.insert(END, item)

def select_events(event=None):
    global current_list

    listbox_events_filtered.insert(END, listbox_events.get(ANCHOR))
    listbox_events.delete(ANCHOR)
    current_list = list(listbox_events_filtered.get(0, END))

def deselect_events(event=None):
    global current_list

    listbox_events.insert(END, listbox_events_filtered.get(ANCHOR))
    listbox_events_filtered.delete(ANCHOR)
    current_list = list(listbox_events_filtered.get(0, END))

def process_list():
    print('current_list:', current_list)
#    for item in current_list:
#        x, y = np.loadtxt(item + '_' + 'Test.csv', skiprows=1, usecols=[my_col_x_axis,
#                          my_col_y_axis], unpack=True, delimiter=',')

my_button = Button(my_window, text='Process current list', command=process_list)
my_button.grid(row=2, column=0, columnspan=3, pady=(0, 10))

listbox_events.bind('<Right>', select_events)
listbox_events_filtered.bind('<Left>', deselect_events)

mainloop()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    相关资源
    最近更新 更多