我在tkinter中遇到了这个问题,我想在其中设置文档的来源,以便我的代码可以使用搜索按钮和askopenfilename在python中处理文件。
这里是我的代码片段。
...
from tkinter import *
from tkinter import filedialog
root = Tk()
root.title("Alpha")
root.iconbitmap('images\alpha.ico')
def search():
global location
root.filename = filedialog.askopenfilename(initialdir="/", title="Select A File",
filetypes=(("txt files", "*.txt"), ("All Files", "*.*")))
location = root.filename
open_button = Button(root, text="Open File", command=search).pack()
input_txt = open(location, "r", encoding="utf8")
...
root.mainloop()
问题:在我运行程序时,窗口短暂打开,我立即收到未完全定义location
变量中的input_txt
的错误。我想我的python代码不是在等我按下程序窗口中的按钮并搜索我的文件,以便可以定义location
。如何在尝试定义open()
之前让python等待location
返回input_txt
的值?
我尝试过
import time
...
location = ''
open_button = Button(root, text="Open File", command=open).pack()
while not location:
time.sleep(0.1)
但是,这导致程序冻结,我知道睡眠不是这里的最佳选择。有什么建议吗?
[像bokinkin所建议的,我建议将input_txt = open(location, ...)
行移到search
函数中。这样,仅当您按下按钮并定义了location
时,程序才会尝试从location
打开。
如果还有其他事情,您可以创建另一个函数并调用它:
def file_handling(location): input_txt = open(location, "r", encoding="utf8") ... #anything using input_txt def search(): root.filename = filedialog.askopenfilename(initialdir="/", title="Select A File", filetypes=(("txt files", "*.txt"), ("All Files", "*.*"))) file_handling(root.filename) open_button = Button(root, text="Open File", command=search) open_button.pack() ... root.mainloop()
问题是,Tkinter对象在到达主循环之前不会执行任何操作,但是一旦进入主循环,就无法返回并填充任何内容。因此,您必须做的所有事情都必须绑定某种输入:例如按下按钮(或击键,或将鼠标悬停在上面)。
在这种情况下,您想设置location
,但是必须等到调用mainloop并且按钮开始接受输入。但是到那时,您已经通过了需要location
且不能返回的行。这就是为什么我建议从input_txt
函数中调用search
行的原因-因为只有在您获得位置之前,它才会被调用。
这有点long,但是我希望它能阐明问题。
我还建议您分别声明和包装小部件。也就是说,更改此:
open_button = Button(root, text="Open File", command=search).pack()
至此:
open_button = Button(root, text="Open File", command=search) open_button.pack()
否则,您最终将存储
pack()
(即None
)的值,而不是存储小部件(Button
对象)。