【问题标题】:Why a file is empty after writing to it?为什么写入文件后文件为空?
【发布时间】:2019-12-31 12:18:04
【问题描述】:

我有一个 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()

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

【问题讨论】:

  • @martineau 哪两个线程?
  • 不要直接使用_thread 模块。你从不想直接访问下划线_modues,除非你确切地知道你在做什么。改用threadingcommand=threading.Thread(None, write_to_file, ()).start.
  • @Dan 首先我初始化列表,然后在 button_click 上开始写入 不,你不是。 write_to_file 首先被调用。您可以通过在每个函数中添加print(name) 来检查它。
  • @Dan,你对线程做了什么尝试?我在评论中展示了什么?因为这对我有用。
  • print(img_list) 添加到write_to_file(),您将看到此函数在开始时执行-无需单击按钮-甚至在运行create_img_list() 之前创建列表,因此write_to_file() 写入空列表。您在command= 中创建并启动thead,并将结果从线程分配给command=,但您应该分配正常函数,该函数稍后将创建线程并启动它。或为此使用lambda - command=lambda:_thread.start_new_thread(write_to_file, ())

标签: python multithreading file tkinter


【解决方案1】:

当我将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()/grid()/place() 返回“无”。

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

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

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

Button(...).pack()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    • 2014-04-12
    • 2014-02-08
    • 1970-01-01
    相关资源
    最近更新 更多