im working on a selenium project using tkinter in python. I want to execute many selenium task at one time(could be up to 100), so I used threading to accomplish this goal, but I came to a problem, due to the fact that I need all individual selenium task to wait a couple seconds between instructions, I used the ‘.after’ method but for some reason my program is still freezing up, I’ve done a lot of research but I cant seem to find the answer yet. Isn’t there a way to use tkinter, threading and some sort of sleeping in python? Do I need to switch to multiprocessing? but I would need all selenium processes to finish within the same 2 minutes and each process takes about a minute.(e.g lets say i start 100, 1 minute processes at 6:00 all task would need to be finished by 6:02)
I created minimal code which mimics my selenium script, so its easier to read, here it is:
from tkinter import * import tkinter as tk import time root = tk.Tk() root.geometry('700x700') import threading class Make: def __init__(self,num): self.num = num.get() Label(root,text='HELLO WORLD WILL PRINT: '+str(self.num)+' times, press go to confirm').pack() Button(root, text='go', command=lambda: self.starting()).pack() def starting(self): for count in range(self.num): t = threading.Thread(target=gogogo()) t.start() def gogogo(): tk.Label(root,text='HELLO WORLD').pack() root.after(2000,print('Please wait 2 seconds')) tk.Label(root,text='You are inside my world').pack() Label(root,text='How many times should I print: HELLO WORLD').pack() num = IntVar() Entry(root, textvariable=num).pack() Button(root, text='Start', command=lambda: Make(num)).pack() root.mainloop()
Advertisement
Answer
You main problem is that after()
and Thread()
similar to command=
needs only function’s name without ()
and it will later use ()
to execute it.
Other problem is that after()
doesn’t stop code but it only send information to mainloop
to execute function after 2000ms
and later Python runs at once next line after after()
. You have to add Label
in fucntion executed by after()
def gogogo(): tk.Label(root, text='HELLO WORLD').pack() print('Please wait 2 seconds') root.after(2000, next_message) # function's name without () def next_message(): tk.Label(root, text='You are inside my world').pack()
# from tkinter import * # PEP8: `import *` is not preferred import tkinter as tk import threading import time class Make: def __init__(self, num): self.num = num.get() text = 'HELLO WORLD WILL PRINT: {} times, press go to confirm'.format(self.num) tk.Label(root, text=text).pack() tk.Button(root, text='go', command=self.starting).pack() def starting(self): for count in range(self.num): t = threading.Thread(target=gogogo) # function's name without () t.start() def gogogo(): tk.Label(root, text='HELLO WORLD').pack() print('Please wait 2 seconds') root.after(2000, next_message) # function's name without () def next_message(): tk.Label(root, text='You are inside my world').pack() # --- main --- root = tk.Tk() root.geometry('700x700') tk.Label(root, text='How many times should I print: HELLO WORLD').pack() num = tk.IntVar() tk.Entry(root, textvariable=num).pack() tk.Button(root, text='Start', command=lambda:Make(num)).pack() root.mainloop()
EDIT: Because gogogo()
runs in separated thread so you can also use time.sleep()
because it doesn’t block mainloop()
in main thread
def gogogo(): tk.Label(root, text='HELLO WORLD').pack() print('Please wait 2 seconds') time.sleep(2) tk.Label(root, text='You are inside my world').pack()