我对python很陌生,一直在使用一个最初用于命令行的程序。因此,它经常使用 input() 函数,尤其是在循环中间。大多数情况下,原始代码会做这样的事情:
for item in list:
# some logic here
user_input - input("prompt")
# uses user_input
我决定要为它制作一个 GUI,但我也想让它成为可选的。我有一个名为 Viewer 的类来装饰原始程序,我正在努力弄清楚如何最好地处理对 input() 的调用。
我的第一个想法只是完全注入一个新的输入函数,这样它就可以在我的 GUI 文本框中查找输入,而不是 sys.stdout。我找到了很多关于如何将 sys.stdout 打印到 GUI 元素(像这样)的 Stack Overflow 答案,但没有找到如何从中获取输入的答案。我所有的尝试要么通过创建循环来冻结 GUI,要么程序不暂停输入,只是在提出提示时抓取框中的内容。
其次,我试图分解我的函数以更好地匹配按钮的代码示例。因此,按钮 1 将触发一个function_part_1,直到需要输入为止。如果 GUI 标志关闭,它将自动转到输入函数,否则它将返回并按下按钮将触发function_part_2:
def function_part_1(list):
item = list[0]
# do some logic on item 1
if GUI:
print("prompt")
return
# After this, the GUI waits for a button press, and then calls function_part_2
else:
function_input(list)
def function_input(list):
user_input = input("prompt")
function_part_2(user_input, list)
def function_part_2(user_input, list):
# uses user_input on item
list.remove(list[0])
if list:
function_part_1(list)
else:
return
然而,这很快就变得丑陋了。首先,它分解了许多循环,这些循环需要大量的重构来保持逻辑的完整性(特别是对于嵌套循环)。它还要求我将所有局部变量从函数部分传递到函数部分,这分解了函数标头。为了只为用户提供一个输入框,GUI 必须具有逻辑来知道哪个功能正在执行以及接下来是哪个功能部分。它使我的函数更难理解并损害可读性。
有没有更好的方法可以做到这一点?
我正在使用appJar作为GUI,它基于Tkinter。如果这会让事情变得更容易,我愿意切换到纯粹的 Tkinter。
最简单的方法是覆盖input
函数。下面是一个使用 tkinter 的工作示例:
import tkinter as tk
def input(prompt=''):
win= tk.Tk()
label= tk.Label(win, text=prompt)
label.pack()
userinput= tk.StringVar(win)
entry= tk.Entry(win, textvariable=userinput)
entry.pack()
# pressing the button should stop the mainloop
button= tk.Button(win, text="ok", command=win.quit)
button.pack()
# block execution until the user presses the OK button
win.mainloop()
# mainloop has ended. Read the value of the Entry, then destroy the GUI.
userinput= userinput.get()
win.destroy()
return userinput
print(input('foobar'))