Python 从tkinter子窗口获取变量
我目前正在用python编写一个脚本,它在脚本开始时接收用户数据,以后可能需要更新这些数据 初始用户数据通过tkinter窗口输入,然后传递给下层函数。在脚本的后面,如果检测到信息不正确,我想提醒用户信息不正确,并提示他们重新输入数据,而不必从头开始启动程序 我试图通过添加一个子窗口函数来实现这一点,该子窗口函数将在需要重新输入数据时调用,获取新的用户输入,然后将其传递回调用它的函数。下面的代码大致显示了我正在尝试执行的操作:Python 从tkinter子窗口获取变量,python,tkinter,Python,Tkinter,我目前正在用python编写一个脚本,它在脚本开始时接收用户数据,以后可能需要更新这些数据 初始用户数据通过tkinter窗口输入,然后传递给下层函数。在脚本的后面,如果检测到信息不正确,我想提醒用户信息不正确,并提示他们重新输入数据,而不必从头开始启动程序 我试图通过添加一个子窗口函数来实现这一点,该子窗口函数将在需要重新输入数据时调用,获取新的用户输入,然后将其传递回调用它的函数。下面的代码大致显示了我正在尝试执行的操作: import tkinter as tk from tkinter
import tkinter as tk
from tkinter import *
def gui():
window = tk.Tk()
window.geometry('300x200')
L1 = tk.Label(window, text = 'This is a test')
L1.grid(column = 1, row = 0)
L2 = tk.Label(window, text = 'Token')
L2.grid(column = 0, row = 1)
E1 = tk.Entry(window, width = 25)
E1.grid(column = 1, row = 1)
B1 = tk.ttk.Button(window, text = 'Run', command = lambda: shell(window, E1.get()))
B1.grid(column = 1, row = 2)
window.mainloop()
def shell(window, val):
print('Old Val:', val)
val = subwindow_test(window)
print('New Val:', val)
def subwindow_test(window):
def subwinfunc(window, val):
if val == None or val == '':
print('Enter something')
else:
window.sub_win.destroy()
return
window.sub_win = tk.Toplevel(window)
window.sub_win.geometry('300x200')
L1 = tk.Label(window.sub_win, text = 'this is a subwindow')
L1.grid(column = 1, row = 0)
L2 = tk.Label(window.sub_win, text = 'New Token')
L2.grid(column = 0, row = 1, sticky = 'E')
var = StringVar()
E1 = tk.Entry(window.sub_win, width = 25, textvariable = var)
E1.grid(column = 1, row = 1)
B1 = tk.ttk.Button(window.sub_win, text = 'Return', command = lambda: subwinfunc(window, var.get()))
B1.grid(column = 1, row = 2)
window.sub_win.mainloop()
return var.get()
gui()
其思想是将窗口向下传递给subwindow_test函数,使用tk.Toplevel生成一个子窗口,向用户请求新数据,然后销毁子窗口并将新输入的数据传递回调用函数
理论上,这将避免我从一开始就重新启动代码,因为这个子窗口测试函数可以从代码中的任何地方运行
问题是,在销毁window.sub_win后,subwinfunc返回后,代码将挂起,直到关闭在gui函数中创建的原始窗口对象。此外,从subwinfunc中删除返回行不会改变这一点
有没有办法绕过这个问题
我尝试过使用一个单独的窗口,一个完全不同的窗口,而不是gui中创建的子窗口,但是同样的问题出现了
据我所知,也不可能将子窗口对象传递回调用函数并在那里关闭它,因为子窗口测试无法返回,直到它从window.sub\u win.mainloop中断。如果返回在mainloop之前,窗口将永远不会出现
此外,我能找到的唯一获得返回值的方法是使用StringVar。我宁愿尝试避免使用全局变量,如果我不得不猜测,我会说返回val.get很可能是问题的根源。然而,因为我找不到从这个函数向上传递变量的其他方法,我被难住了。您不应该多次调用mainloop。Tkinter提供了在继续使用wait_window方法之前等待窗口关闭的功能
下面是一个非常简单的示例,演示如何创建一个弹出对话框,直到用户单击“确定”或“取消”按钮后才会返回
def get_input():
value = None
def do_ok(event=None):
nonlocal value
value = entry.get()
top.destroy()
def do_cancel():
nonlocal value
value = None
top.destroy()
top = tk.Toplevel()
entry = tk.Entry(top)
ok = tk.Button(top, text="ok", command=do_ok)
cancel = tk.Button(top, text="cancel", command=do_cancel)
entry.bind("<Return>", do_ok)
entry.pack(side="top", fill="x")
ok.pack(side="right")
cancel.pack(side="left")
top.wait_window(top)
return value