Home > Mobile >  How to trigger again a callback function before the first call for that function has ended
How to trigger again a callback function before the first call for that function has ended

Time:10-08

Good morning,

What I am aiming for:

  • I want to create a button that when clicked triggers a call back function (even if that function is still running).

Module:

  • I am using tkinter

Problem:

  • When I trigger the button, the function runs, but then I cannot push the button again before the function has finished its run. I want to be able to push the button while the function is still running and have the function stop and run again from start.

My attempts:

  • I tried both a procedural and a OOP approach: both present the same problem

My attempt n1: Procedural approach

import time
import tkinter as tk # Import tkinter
from tkinter import ttk # Import ttk

def func():
    for i in range (100):
        print(i)
        time.sleep(5)


win = tk.Tk() # Create instance of the Tk class
aButton = ttk.Button(win, text="Click Me!", command=func)
aButton.grid(column=0, row=0) # Adding a Button
win.mainloop() #  Start GUI

My attempt n2: OOP approach

import time
import tkinter as tk # Import tkinter
from tkinter import ttk # Import ttk

class OOP():
    def func(self):
        for i in range (100):
            print(i)            
            time.sleep(5)

    def __init__(self):
        win = tk.Tk() # Create instance of the Tk class
        aButton = ttk.Button(win, text="Click Me!", command=self.func) 
        aButton.grid(column=0, row=0) # Adding a Button
        win.mainloop() #  Start GUI

oop = OOP()

Thanks

CodePudding user response:

In tkinter, as with most GUI frameworks, there is a for loop running somewhere that constantly checks for user input. You are hijacking that loop to do your func processing. Tkinter can not check for user input, nor e.g. change the appearance of the button icon, because there is only one thread and you are using it.

What you will want to do is fire up a thread or process to do the work. There are lots of libraries to do parallel processing in elaborate ways if you have lots of background tasks but this will do for a single function (see also this answer).

import time
import tkinter as tk # Import tkinter
from tkinter import ttk # Import ttk
import threading

def button():
    thread = threading.Thread(target=func, args=args)
    thread.start()

def func():
    for i in range (100):
        print(i)
        time.sleep(5)


win = tk.Tk() # Create instance of the Tk class
aButton = ttk.Button(win, text="Click Me!", command=button)
aButton.grid(column=0, row=0) # Adding a Button
win.mainloop() #  Start GUI

If the process is long running, you might need to find a way to clean up the threads when they're done.

  • Related