如何杀死在tkinter中运行的线程\进程?

时间:2017-03-21 02:56:46

标签: python multithreading tkinter

所以假设我有一个Tkinter GUI,它显示一个RUN按钮,一个STOP按钮和一个ScrolledText小部件。按RUN按钮将调用包含多个log.info()呼叫的功能。文本小部件应该显示那些日志。我希望这些日志在发生时能够实时显示,所以我尝试将该功能作为线程运行,并希望按下STOP按钮终止该功能。这就是我现在所拥有的:

我的代码:

import tkinter as tk
import logging
import tkinter.scrolledtext as tkst
import threading

class TextHandler(logging.Handler):
    """This class allows you to log to a Tkinter Text or ScrolledText widget"""
    def __init__(self, text):
        # run the regular Handler __init__
        logging.Handler.__init__(self)
        # Store a reference to the Text it will log to
        self.text = text

    def emit(self, record):
        msg = self.format(record)
        def append():
            self.text.configure(state='normal')
            self.text.insert(tk.END, msg + '\n')
            self.text.configure(state='disabled')
            # Autoscroll to the bottom
            self.text.yview(tk.END)

        # This is necessary because we can't modify the Text from other threads
        self.text.after(0, append)

def setup_logger(logger_name, log_file, level=logging.INFO):    

    l = logging.getLogger(logger_name)
    formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')

    if path.exists(log_file) == False:          
        fileHandler = logging.FileHandler(log_file, mode='w')

    else:
        fileHandler = logging.FileHandler(log_file, mode='a')

    fileHandler.setFormatter(formatter) 
    streamHandler = logging.StreamHandler()
    streamHandler.setFormatter(formatter)

    l.setLevel(level)
    l.addHandler(fileHandler)
    l.addHandler(streamHandler)


setup_logger('logA', 'HeresTheLog.log')
log = logging.getLogger('logA')


def threadding():
    app.running = True;
    newthread = threading.Thread(target= function)
    newthread.start()

def function():
    log.info("starts")
    (do things)
    log.info("ends")

def stop():
    app.running = False;

class myApp(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self, width=768, height=576, bg="")
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)     
        container.grid_columnconfigure(0, weight=1)

        self.running = True

        self.frames = {}
        self.show_frame(StartPage)
        self.update_idletasks()

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()




class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)

        button2 = ttk.Button(self, text="FUNCTION", 
                            command= function
                             )
        button2.pack(pady=10)



        textLog = tkst.ScrolledText(self, state="disabled")
        textLog.pack()

        text_handler = TextHandler(textLog)
        log.addHandler(text_handler)

        stopbutton = ttk.Button(self, text = "STOP!", command = stop)
        stopbutton.pack()




app = myApp()
app.mainloop()

基本上,我正在尝试使用app.running来控制线程,但这似乎不起作用。我知道你不能真正杀死线程。所以我想知道更好的方法是什么?也许使用多进程而不是线程,以便我们可以杀死它来阻止它?有人可以详细说明这个想法吗?

0 个答案:

没有答案