Francesco
Francesco

Reputation: 121

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

Good morning,

What I am aiming for:

Module:

Problem:

My attempts:

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

Upvotes: 1

Views: 462

Answers (1)

FiddleStix
FiddleStix

Reputation: 3731

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.

Upvotes: 1

Related Questions