让python通过tkinter等待设置变量

问题描述 投票:0回答:1

我在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)

但是,这导致程序冻结,我知道睡眠不是这里的最佳选择。有什么建议吗?

python button tkinter block wait
1个回答
0
投票

关于您的问题

[像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对象)。

© www.soinside.com 2019 - 2024. All rights reserved.