[Tkinter] GUI Freeze/tkinter - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: [Tkinter] GUI Freeze/tkinter (/thread-19350.html) |
GUI Freeze/tkinter - SamGer - Jun-24-2019 Hello Users, I have a python script called Master which runs continously (using while 1:). Now I want to create a simple GUI using tkinter to Start and Stop the Master script but once started, the GUI does not react and as far as I have read online, this issuse can be solved using Threading. But it seems I am not using the Threading in a correct manner as I am getting Exceptions because of this approach: Will be greatful to your suggestionsMy Code Looks as follows: Master: def Excecute(): while 1: func1() func2() # and many other functionsGUI: import Tkinter import tkSimpleDialog import tkFileDialog import tkMessageBox import os from subprocess import Popen import sys import Master as test import threading class PST(Tkinter.Tk): def __init__(self,parent): Tkinter.Tk.__init__(self,parent) self.parent = parent self.initialize() def initialize(self): # Label self.grid() d="Sample Text" label1 = Tkinter.Label(self,text="Status :" + self.Status_Text(d),anchor="w").grid(column=0,row=0,columnspan=1,sticky='EW',padx=5,pady=5) # Button button1 = Tkinter.Button(self,text=u"Start",command=self.anfang) button1.grid(column=0,row=11,pady=10,padx=10,columnspan=1,sticky='W') button2 = Tkinter.Button(self,text=u"Beenden",command=self.beenden) button2.grid(column=0,row=11,pady=10,padx=90,sticky='W') def anfang(self): t=threading.Thread(target=test.Execute) t.start() def Status_Text(self,Meldung): Text=Meldung return (Text) def beenden(self): print("Exiting") self.destroy() sys.exit() master = CoA_PST(None) master.title('CoA PST') w = 300 h = 100 ws = master.winfo_screenwidth() hs = master.winfo_screenheight() x = (ws/2) - (w/2) y = (hs/2) - (h/2) master.geometry('%dx%d+%d+%d' % (w, h, x, y)) master.mainloop() RE: GUI Freeze/tkinter - Yoriz - Jun-24-2019 Using the methods shown in thread https://python-forum.io/Thread-Tkinter-How-to-deal-with-code-that-blocks-the-mainloop-freezing-the-gui import functools import time import tkinter as tk from concurrent import futures thread_pool_executor = futures.ThreadPoolExecutor(max_workers=1) def tk_after(target): @functools.wraps(target) def wrapper(self, *args, **kwargs): args = (self,) + args self.after(0, target, *args, **kwargs) return wrapper def submit_to_pool_executor(executor): '''Decorates a method to be sumbited to the passed in executor''' def decorator(target): @functools.wraps(target) def wrapper(*args, **kwargs): result = executor.submit(target, *args, **kwargs) result.add_done_callback(executor_done_call_back) return result return wrapper return decorator def executor_done_call_back(future): exception = future.exception() if exception: raise exception def func1(): time.sleep(2) def func2(): time.sleep(3) class MainFrame(tk.Frame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.run_thread = False self.label = tk.Label(self, text='not running') self.label.pack() self.button = tk.Button( self, text='start task', command=self.on_button) self.button.pack(pady=15) self.pack() def on_button(self): if not self.run_thread: self.run_thread = True self.blocking_code() self.set_button_text('Stop task') else: self.run_thread = False self.set_button_state(False) self.set_button_text('Stopping') self.blocking_code_stopped() @tk_after def set_label_text(self, text=''): self.label['text'] = text @tk_after def set_button_text(self, text=''): self.button['text'] = text @tk_after def set_button_state(self, enable=True): state = 'normal' if enable else 'disable' self.button['state'] = state @submit_to_pool_executor(thread_pool_executor) def blocking_code(self): self.set_label_text('running') while self.run_thread: func1() self.set_label_text('func1 complete') func2() self.set_label_text('func2 complete') @submit_to_pool_executor(thread_pool_executor) def blocking_code_stopped(self): self.set_button_state(True) self.set_label_text('not running') self.set_button_text('Start task') if __name__ == '__main__': app = tk.Tk() main_frame = MainFrame() app.mainloop() RE: GUI Freeze/tkinter - noisefloor - Jun-24-2019 Hi, a more simple approach would be start the thread outside Tkinter and share an event between the GUI class and the thread. The functions are run by setting the event, like while event.is_set(): .Except this: while 1 is not pythonic, use while True instead. Function names are written in lower case letter, so the function should be names execute . You are using Python 2, which is EOL at the end of this year. Better switch to Python 3 NOW.And finally @SamGer: you are aware that there is a German-language based forum for Python at python-forum.de? Nothing against posting here, but probably it's a bit more convenient to get high quality answers in your mother language. Regards, noisefloor |