我已经将一个Tkinter GUI
编码为控制台来控制某些内容。而且,我还想从APScheduler
模块运行一个调度程序来完成一项工作,该工作每20秒执行一次操作。
但是,这两个线程似乎无法一起运行。
我尝试使用multi-threading
,但似乎不起作用。
import tkinter as tk
from tkinter import *
import time
import pyHook
import winreg
import webbrowser
import os
import pyautogui
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.schedulers.background import BackgroundScheduler
import threading
def initialization():
webbrowser.open('AutoRefreshSCMOutbound.HTML', 1)
time.sleep(2)
def autoClick():
x, y = pyautogui.size()
pyautogui.click(x/2, y/2, button='left')
time.sleep(1)
pyautogui.click(x/2, y/2, button='left')
return True
root = tk.Tk()
root.geometry('700x100')
root.resizable(height = True, width = True)
root.overrideredirect(False)
OneBtn = Button(root, command = initialization, text = "One Button", width = '30')
OneBtn.grid(row = 1 ,column = 0)
if __name__ == "__main__":
th01 = threading.Thread(target=root.mainloop())
scheduler = BackgroundScheduler
scheduler.add_job(autoClick, 'interval', seconds=20)
threads = []
th01.start()
scheduler.start()
threads.append(th01)
threads.append(scheduler)
for t in threads:
t.join()
print("End all process")
这2个线程应该在同一时间运行,但是调度程序总是需要等到Tkinter结束。
答案 0 :(得分:0)
在tkinter
中,您可以使用root.after(time_in_millisecond, function_name)
来延迟执行功能。 root.after
仅执行一次功能,因此您必须在此功能内再次使用root.after
。
import tkinter as tk
import time
import webbrowser
import pyautogui
def initialization():
webbrowser.open('AutoRefreshSCMOutbound.HTML', 1)
time.sleep(2)
def autoClick():
# run again after 20000ms (20s)
root.after(20000, autoClick)
x, y = pyautogui.size()
pyautogui.click(x/2, y/2, button='left')
time.sleep(1)
pyautogui.click(x/2, y/2, button='left')
if __name__ == "__main__":
root = tk.Tk()
root.geometry('700x100')
root.resizable(height = True, width = True)
root.overrideredirect(False)
OneBtn = tk.Button(root, command=initialization, text="One Button", width='30')
OneBtn.grid(row=1, column=0)
# run first time after 20000ms (20s)
root.after(20000, autoClick)
root.mainloop()
或将其他功能与after()
一起使用来执行您不想修改的功能。
import tkinter as tk
import time
import webbrowser
import pyautogui
def initialization():
webbrowser.open('AutoRefreshSCMOutbound.HTML', 1)
time.sleep(2)
def autoClick():
x, y = pyautogui.size()
pyautogui.click(x/2, y/2, button='left')
time.sleep(1)
pyautogui.click(x/2, y/2, button='left')
def repeate():
# run again after 20000ms (20s)
root.after(20000, repeate)
autoclick()
if __name__ == "__main__":
root = tk.Tk()
root.geometry('700x100')
root.resizable(height = True, width = True)
root.overrideredirect(False)
OneBtn = tk.Button(root, command=initialization, text="One Button", width='30')
OneBtn.grid(row=1, column=0)
# run first time after 20000ms (20s)
root.after(20000, repeate)
root.mainloop()
但是after()
仅在执行的函数不能运行太长时间时才有用,因为此时它仍然阻塞mainloop()
(和程序的其余部分)。因为autoClick
使用sleep(1)
,所以它会停止所有程序1秒钟。
如果其他函数的运行时间不长,则after()
很有用,因为它可能会阻塞mainloop()
来执行由after()
添加的函数。 initialization
使用sleep(2)
,因此可能会阻塞执行autoClick
2秒钟。
要在没有sleep(1)
的情况下运行它,可以将函数分为两个函数,然后使用after(1000, second_part)
执行第二部分
def repeate():
# run again after 20000ms (20s)
root.after(20000, repeate)
autoclick()
def autoClick():
x, y = pyautogui.size()
pyautogui.click(x/2, y/2, button='left')
root.after(1000, autoClick_second_part) # 1000ms (1s)
def autoClick_second_part():
pyautogui.click(x/2, y/2, button='left')