Home > OS >  python tkinter: Calling a objects method on button click does not work
python tkinter: Calling a objects method on button click does not work

Time:02-23

here is my sample code:

from time import  sleep
import tkinter as tk
import threading


class Action:

    counter = 0

    def do_something(self):
        while True:
            print('Looping')
            sleep(5)


action = Action()
root = tk.Tk()

button = tk.Button(root, text='pressme harder', command=threading.Thread(target=action.do_something()).start())
button.grid(row=1, column=0)

root.mainloop()

What am I expecting? I'm expecting that as soon as I click the button in the UI an new thread is running, which is looping in the background and does not interfere with the UI (or later maybe other threads doing tasks in the background)

What is really happening? When running the code, the method of the class is executeds immdiately and locking the procedure. root.mainloop() is never reached and therefore no UI is drawn

Alternatively I tried the following change:

button = tk.Button(root, text='pressme harder', command=threading.Thread(target=lambda: action.do_something()).start())

This behaves in the following (imho wrong) way: The method is also called immediately, without pressing the button. This time the UI is drawn but seems the be locked by the thread (UI is slow/stuttering, pressing the buttom does not work most of the time)

Any Idea whats wrong there? Or how do I handle this in a more stable way?

CodePudding user response:

You shouldn't try to start a thread directly in the button command. I suggest you create another function that launches the thread.

from time import sleep
import tkinter as tk
import threading


class Action:
    counter = 0
    def do_something(self):
        while True:
            print('Looping')
            sleep(2)
            print("Finished looping")
            
    def start_thread(self):
        thread = threading.Thread(target=self.do_something, daemon=True)
        thread.start()


action = Action()
root = tk.Tk()

button = tk.Button(root, text='pressme harder', command=action.start_thread)
button.grid(row=1, column=0)

root.mainloop()
  • Related