使用 Tkinter、Threading 和 After 方法

Using Tkinter, Threading and After method

我正在 python 中使用 tkinter 开发一个 selenium 项目。我想一次执行很多 selenium 任务(最多 100 个),所以我使用线程来实现这个目标,但是我遇到了一个问题,因为我需要所有单独的 selenium 任务等待几秒钟在指令之间,我使用了“.after”方法但由于某种原因我的程序仍然冻结,我做了很多研究但我似乎无法找到答案。 python 中没有使用 tkinter、线程和某种休眠的方法吗?我需要切换到多处理吗?但我需要所有 selenium 进程在相同的 2 分钟内完成,每个进程大约需要一分钟。(例如,假设我在 6:00 开始 100 个 1 分钟的进程,所有任务都需要在 6:02)

我创建了模仿我的 selenium 脚本的最少代码,因此它更容易阅读,这里是:

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()

你的主要问题是 after()Thread() 类似于 command= 只需要函数名而不需要 () 稍后将使用 () 来执行它。

另一个问题是 after() 不会停止代码,但它只会将信息发送到 mainloop 以在 2000ms 之后执行函数,然后 Python 立即运行after() 之后的行。您必须在 after()

执行的函数中添加 Label
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()

编辑: 因为 gogogo() 在单独的线程中运行所以你也可以使用 time.sleep() 因为它不会在主线程中阻塞 mainloop()线程

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()