Python tkinter在我调用pyautogui命令时不断崩溃

Python tkinter在我调用pyautogui命令时不断崩溃,python,tkinter,pyautogui,Python,Tkinter,Pyautogui,我最近一直在尝试让简单的程序与tkinter和pyautogui一起工作 一个没有tkinter的单独按钮可以很好地工作,但是当我决定开始用GUI将它们制作成tkinter时,它一直崩溃,我认为发生这种情况的原因是,即使我键入了root.update(),按钮也一直被按下,但它似乎不再被按下,而是被按下并执行命令 没有tkinter的代码可以工作: import pyautogui,time time.sleep(5) f = open("mytext.txt", 'r')

我最近一直在尝试让简单的程序与tkinter和pyautogui一起工作 一个没有tkinter的单独按钮可以很好地工作,但是当我决定开始用GUI将它们制作成tkinter时,它一直崩溃,我认为发生这种情况的原因是,即使我键入了
root.update()
,按钮也一直被按下,但它似乎不再被按下,而是被按下并执行命令

没有tkinter的代码可以工作:

import pyautogui,time
time.sleep(5)
f = open("mytext.txt", 'r')
time.sleep(5)
for word in f:
    pyautogui.typewrite(word)

使用tkinter:

import tkinter as tk
import pyautogui,time
root = tk.Tk()
def stop_writing():
    global btn 
    btn.config(command = None)
def write():
    root.update()

    time.sleep(5)
    f = open("mytext.txt", 'r')

    for word in f:
        pyautogui.typewrite(word)
    pyautogui.mainloop()

btn = tk.Button(root, text = "start writing" , command = write)
btn.pack()     
btn_disable = tk.Button(root, text = "stop writing" ,command = stop_writing)
btn_disable.pack()
root.mainloop()


有没有办法阻止它崩溃?

阻止Tkinter崩溃的唯一方法是不要在主线程中使用
time.sleep

我建议您为
pyautogui.typewrite
创建一个单独的线程。另外,请注意,您不应该从不同的线程更新Tkinter组件,因为Tkinter不是线程安全的

我将展示如何使用多线程实现这一点

import tkinter as tk
import pyautogui,time, threading


def stop_writing():
    global _stop, thread
    if thread:
        _stop = True
        thread.join()

def write():
    
    time.sleep(2)
    with open(r"file.txt", 'r') as f:
        content = f.read()

    for word in content:
        if _stop:
            return
        pyautogui.typewrite(word)


def start():
    global thread, _stop

    if thread and thread.is_alive():
        stop_writing()

    thread = None
    thread = threading.Thread(target=write)
    thread.daemon = True
    _stop = False
    thread.start()
    

root = tk.Tk()
root.attributes('-topmost', True)
root.protocol("WM_DELETE_WINDOW", lambda: [stop_writing(), root.destroy()])
_stop = False
thread = None

btn = tk.Button(root, text = "start writing" , command = start)
btn.pack()     
btn_disable = tk.Button(root, text = "stop writing" ,command = stop_writing)
btn_disable.pack()

text = tk.Text(root)
text.pack()

root.mainloop()

您还可以使用
root.after
并在几秒钟后调用write函数

一些小错误:

  • 如果打开文件,应始终将其关闭
  • 我查看了pyautogui文档,但找不到任何方法,比如mainloop