首页 > 解决方案 > 为什么写入文件后文件为空?

问题描述

我有一个 tkinter 应用程序和一个将一些数据写入文件的线程。如果我让线程完成它的工作,则文件为空。如果我在线程完成之前终止程序(单击 pyCharm 中的红色方块),则文件将填充数据直到终止点。这是重现问题的代码:

import tkinter as tk
import _thread
import numpy as np

img_list = []


def create_img_list():
    for i in range(1000):
        img = np.random.rand(385, 480)
        img = img * 65535
        img = np.uint16(img)
        img_list.append(img)


def write_to_file():
    f = open("test.Raw", "wb")
    for img in img_list:
        f.write(img)
    f.close()


root = tk.Tk()
button = tk.Button(root, text="Click Me", command=_thread.start_new_thread(write_to_file, ())).pack()
create_img_list()
root.mainloop()

这是怎么回事,我该如何解决?

标签: pythonmultithreadingfiletkinter

解决方案


当我添加print(img_list)时,write_to_file()我看到这个函数在开始时执行 - 没有点击按钮 - 甚至在create_img_list()运行之前(创建列表)所以write_to_file()写空列表。

你使用command=不当。它需要没有函数名()(所谓的“回调”),但是您运行函数并将其结果分配给command=. 你的代码像

result = _thread.start_new_thread(write_to_file, ()) # it executes function at start

button = tk.Button(root, text="Click Me", command=result).pack()

但你需要

def run_thread_later():
    _thread.start_new_thread(write_to_file, ())

button = tk.Button(root, text="Click Me", command=run_thread_later).pack()

最终您可以使用lambda直接在command=

button = tk.Button(root, text="Click Me", command=lambda:_thread.start_new_thread(write_to_file, ())).pack()

顺便说一句:你有常见的错误

button = Button(...).pack()

分配None给变量,因为//pack()返回`None.grid()place()

如果您button稍后需要访问,则必须分两行进行

button = Button(...)
button.pack()

如果您以后不需要访问button,则可以跳过 `button()

Button(...).pack()

推荐阅读