问题描述
我对 python 非常陌生,并且一直在使用一个最初用于命令行的程序.因此,它大量使用 input() 函数,尤其是在循环中间.大多数情况下,原始代码会执行以下操作:
I am pretty new to python and have been working with a program that was originally meant for the command line. As such, it uses the input() function quite a bit, especially in the middle of loops. Mostly, the original code would do something like this:
for item in list:
# some logic here
user_input - input("prompt")
# uses user_input
我决定为它制作一个 GUI,但我也想让它成为可选的.我有一个名为 Viewer 的类来装饰原始程序,我正在努力弄清楚如何最好地处理对 input() 的调用.
I've decided I want to make a GUI for it, but I also want to make it optional. I have a class called Viewer that decorates the original program, and I am struggling to figure out how to best to handle the calls to input().
我的第一个想法是完全注入一个新的输入函数,这样它就可以在我的 GUI 文本框中而不是 sys.stdout 中查找输入.我找到了许多关于如何将 sys.stdout 打印到 GUI 元素的 Stack Overflow 答案(例如 this),但不是如何从一个那里获取输入.我的所有尝试要么以通过创建循环而冻结 GUI 告终,要么程序不暂停输入并在提示出现时简单地抓取框中的内容.
My first thought was just to inject a new input function altogether so that way it looks for input in my GUI text box instead the sys.stdout. I found many Stack Overflow answers on how to print sys.stdout to a GUI element (like this), but not how to take input from one. All of my attempts either ended in freezing the GUI by creating a loop, or the program not pausing for input and simply grabbing what was in the box when the prompt was put forward.
其次,我尝试分解我的函数以更好地匹配按钮的代码示例.因此,按钮 1 将触发 function_part_1,直到它需要输入为止.如果GUI标志被关闭,它会自动进入一个输入函数,否则它会返回并且按下按钮会触发function_part_2:
Secondly, I tried to break apart my functions to better match the code examples for buttons. So, button 1 would trigger a function_part_1, which would go until it required an input. If the GUI flag was turned off, it would automatically go to an input function, otherwise it would return and a button press would trigger 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 必须有逻辑来知道正在执行哪个功能以及接下来是哪个功能部分.它使我的功能更难以遵循并损害可读性.
However, this turned ugly really quickly. First, it broke apart many loops which would require a lot of refactoring to keep the logic in tact (Especially for the nested loops). It also requires that I pass all my local variables from function-part to function-part, which exploded the function headers. In order to have only a single input box for the user, the GUI has to have logic to know which function is executing and what function-part comes next. It made my functions harder to follow and hurt readability.
有没有更好的方法来做到这一点?
Is there a nicer way to do this?
我将 appJar 用于 GUI,它基于 Tkinter.如果这会让事情变得更容易,我愿意切换到纯 Tkinter.
I am using appJar for the GUI, which is based around Tkinter. I am willing to switch to pure Tkinter if that would make things easier.
推荐答案
最简单的方法是覆盖 input
函数.这是一个使用 tkinter 的工作示例:
The easiest way is to overwrite the input
function. Here's a working example using 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'))
这篇关于在 GUI 中替换 Python 程序的 input() 部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!