【问题标题】:tkinter: RuntimeError: threads can only be started oncetkinter:RuntimeError:线程只能启动一次
【发布时间】:2019-06-21 01:32:14
【问题描述】:

但我正在尝试为我的脚本制作 GUI,当我单击 bt_send 时,我启动了一个线程 (thread_enviar),该线程也启动了其他线程 (core),问题是 @987654325 @ 一直在运行,所以当我再次尝试单击 bt_send 时出现此错误:

文件“/anaconda3/envs/tensor/lib/python3.6/threading.py”,第 842 行,开始 raise RuntimeError("线程只能启动一次") RuntimeError: 线程只能启动一次

我的代码:

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()

我不知道是否有任何方法可以杀死该线程或者我做错了什么。

【问题讨论】:

  • “那个线程也启动其他线程(核心)”Edit你的问题并详细解释为什么你选择这样做threadthread.
  • 我在第一个线程中得到了一些验证,以便执行第二个线程。
  • thread_enviar "is running for ever"为什么你必须多次启动它一次
  • 我的意思是当我按下按钮时它永远不会结束,但我需要 thread_enviar 在核心之后立即结束,这样用户就可以再次运行该进程。顺便说一句,线程核心大约需要 2-3 分钟。

标签: python multithreading tkinter


【解决方案1】:

问题:RuntimeError:线程只能启动一次

据我了解,您不想运行多个threads,只想在thread 中执行一个任务以避免冻结Tk().mainloop()
要禁止,要在前一个 thread 仍在运行时启动一个新的 thread,您必须 disable Button 或验证前一个 thread 是否仍然是 .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()

【讨论】:

  • 像魅力一样工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-09
  • 2015-03-24
相关资源
最近更新 更多