Reputation: 15
but I'm trying to make the GUI for my script, when I click bt_send
I start a thread (thread_enviar
), that thread also start other thread (core
), the problem is that thread_enviar
is running for ever so I got this error when I try to click bt_send
again:
File "/anaconda3/envs/tensor/lib/python3.6/threading.py", line 842, in start raise RuntimeError("threads can only be started once") RuntimeError: threads can only be started once
My code:
import tkinter as tk
from tkinter import filedialog
import pandas as pd
from tkinter import messagebox
from tkinter import ttk
import threading
import rnn10forecasting as rnn10f
filepath = ""
model = ""
'''def change_menu(selection):
global model
selected = selection
print(selected)
model = selected'''
def click():
global filepath
print("click")
filepath = filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = (("data files","*.csv"),("all files","*.*")))
print(filepath)
label_filepath.config(text = filepath)
def enviar():
print(filepath)
try:
data = pd.read_csv(filepath)
except:
messagebox.showerror("Error", "Archivo .csv vacio o formato incompatible")
if any(data.columns.values != ['date','close','volume','open','high','low']):
messagebox.showerror("Error", "El archivo .csv no contiene la estructura requerida: [date,close,volume,open,high,low]")
elif len(data) < 300:
print("# registros")
print(len(data))
messagebox.showerror("Error", "El archivo de be contener como minimo 700 registros")
else:
pg_bar.start(500)
core = threading.Thread(target=rnn10f.forecasting, args=(filepath,))
#core.daemon = True
core.start()
core.join()
print("VIVO?")
print(core.isAlive())
pg_bar.stop()
return print(thread_enviar.is_alive())
thread_enviar = threading.Thread(target=enviar, args=())
window = tk.Tk()
window.resizable(width=False, height=False)
window.title("LSTM Module")
window.geometry("600x150")
title = tk.Label(text="StockForecaster", font=("Times New Roman", 30))
title.place(relx=0.1, rely=0.05, relwidth=0.8, relheight=0.25)
bt_select = tk.Button(text="Select File", bg="blue", command= click)
bt_select.place(relx=0.7, rely=0.4, relwidth=0.25, relheight=0.2)
label_filepath = tk.Label(text="Please select a .csv File")
label_filepath.place(relx=0, rely=0.4, relwidth=0.7, relheight=0.15)
options = tk.StringVar()
bt_send = tk.Button(text="Send", bg="blue", command=thread_enviar.start)
bt_send.place(relx=0.70, rely=0.7, relwidth=0.25, relheight=0.20)
pg_bar = ttk.Progressbar(window, orient= tk.HORIZONTAL, mode="indeterminate", )
pg_bar.place(relx=0.10, rely=0.75, relwidth=0.55, relheight=0.05)
window.mainloop()
I don' know if there is any way to kill that thread or If I'm doing something wrong.
Upvotes: 1
Views: 2412
Reputation: 15533
Question: RuntimeError: threads can only be started once
As I understand, you don't want to run multiple threads
, you only want to do a Task in a thread
to avoid freezing the Tk().mainloop()
.
To inhibit, to start a new thread
while the previous thread
are still running you have to disable
the Button
or verify if the previous thread
is still .alive()
.
import tkinter as tk
import threading, time
class Task(threading.Thread):
def __init__(self, master, task):
threading.Thread.__init__(self, target=task, args=(master,))
if not hasattr(master, 'thread_enviar') or not master.thread_enviar.is_alive():
master.thread_enviar = self
self.start()
def enviar(master):
# Simulating conditions
if 0:
pass
#if any(...
#elif len(data) < 300:
else:
#master.pg_bar.start(500)
# Simulate long run
time.sleep(10)
#rnn10f.forecasting(filepath)
print("VIVO?")
#master.pg_bar.stop()
class App(tk.Tk):
def __init__(self):
super().__init__()
bt_send = tk.Button(text="Send", bg="blue",
command=lambda :Task(self, enviar))
if __name__ == "__main__":
App().mainloop()
Upvotes: 1