Reputation: 33
I got a tkinter app and a thread which writes some data to a file. If I let the thread finish it's job, the file is empty. If I terminate the program before the thread is done (clicking the red square in pyCharm) the file is filled with the data till the point of termination. Here is a code to reproduce the problem:
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()
What is going on here and how do I fix it?
Upvotes: 1
Views: 269
Reputation: 142681
When I add print(img_list)
to write_to_file()
I see that this function is executed at start - without clicking button - even before create_img_list()
runs (which creates list) so write_to_file()
writes empty list.
You use command=
incorrectly. It needs function name without ()
(so called "callback") but you run function and you assign its result to command=
. Your code works like
result = _thread.start_new_thread(write_to_file, ()) # it executes function at start
button = tk.Button(root, text="Click Me", command=result).pack()
but you need
def run_thread_later():
_thread.start_new_thread(write_to_file, ())
button = tk.Button(root, text="Click Me", command=run_thread_later).pack()
Eventually you can uses lambda
to create this function directly in command=
button = tk.Button(root, text="Click Me", command=lambda:_thread.start_new_thread(write_to_file, ())).pack()
BTW: you have common mistake
button = Button(...).pack()
which assign None
to variable because pack()
/grid()
/place()
return `None.
If you need access button
later then you have to do it in two lines
button = Button(...)
button.pack()
If you don't need access button
later then you can skip `button()
Button(...).pack()
Upvotes: 1