Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么文件写入后为空?_Python_Multithreading_File_Tkinter - Fatal编程技术网

Python 为什么文件写入后为空?

Python 为什么文件写入后为空?,python,multithreading,file,tkinter,Python,Multithreading,File,Tkinter,我有一个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.ran

我有一个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()
这里发生了什么以及如何修复它?

当我将
打印(img\u列表)
添加到
写入文件()
时,我看到这个函数在开始时执行,没有点击按钮,甚至在
创建img\u列表()
运行(创建列表)之前执行,所以
写入文件()
写入空列表

您错误地使用了
命令=
。它需要不带
()
(所谓的“回调”)的函数名,但您运行函数并将其结果分配给
命令=
。您的代码的工作方式如下

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()
返回`None'

如果以后需要访问
按钮
,则必须分两行执行

button = Button(...)
button.pack()
如果以后不需要访问
按钮
,则可以跳过`button()


@martineau哪两个线程?不要直接使用
\u thread
模块。除非您确切知道自己在做什么,否则您永远不想直接访问下划线
\u modues
。改为使用
threading
command=threading.Thread(无,写入文件,())。开始。
@Dan首先初始化列表,然后单击按钮开始写入否,您没有<首先调用代码>写入文件。您可以通过向每个函数添加
print(name)
来检查它。@Dan,您在线程方面做了哪些尝试?我在评论中表现了什么?因为这对我有用。添加
print(img\u list)
write\u-to\u-file()
,您将看到此函数在开始时执行,而无需单击按钮,甚至在运行创建列表的
create\u-img\u-list()
之前执行,因此
write\u-to-file()
写入空列表。您可以在
命令=
中创建并启动AD,并将结果从线程分配给
命令=
,但您应该分配普通函数,该函数稍后将创建线程并启动它。或者使用
lambda
执行此命令-
命令=lambda:\u线程。启动新线程(写入文件,())
Button(...).pack()