You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

制作闲置自动关机程序:Tkinter弹窗与PyAutoGUI联动问题求助

解决Tkinter弹窗与PyAutoGUI的自动响应联动问题

你的核心问题是Tkinter的messagebox.askyesno()是阻塞式函数——它会卡住整个程序,直到用户手动点击按钮,所以你写在它后面的PyAutoGUI代码根本没机会在等待用户响应的30秒内执行。要实现超时自动点击的需求,得换一种非阻塞的弹窗实现方式,结合Tkinter的after()定时器来完成。

改进方案代码

import tkinter as tk
from tkinter import ttk
import pyautogui
import time

def create_wake_check_popup():
    # 创建主窗口(隐藏,只显示弹窗)
    root = tk.Tk()
    root.withdraw()

    # 自定义弹窗窗口
    popup = tk.Toplevel(root)
    popup.title("Yes No Demo")
    popup.geometry("300x150")
    popup.attributes("-topmost", True)  # 弹窗置顶

    # 弹窗内容
    tk.Label(popup, text="Are you awake?", font=("Arial", 12)).pack(pady=10)
    tk.Label(popup, text="Click No to stay active", font=("Arial", 10)).pack(pady=5)

    # 定义按钮点击后的处理逻辑
    timer_id = None
    def on_yes_click():
        nonlocal timer_id
        if timer_id:
            root.after_cancel(timer_id)  # 取消定时器
        popup.destroy()
        root.destroy()
        # 用户点击Yes后的逻辑:这里可以替换成你需要的操作,比如继续等待闲置
        time.sleep(3)
        create_wake_check_popup()  # 再次弹出检测窗口

    def on_no_click():
        nonlocal timer_id
        if timer_id:
            root.after_cancel(timer_id)
        popup.destroy()
        root.destroy()
        # 用户点击No后的逻辑:退出循环(比如触发关机)
        print("Shutting down...")

    # 设置30秒超时自动点击No按钮
    def auto_click_no():
        no_btn.invoke()  # 直接调用No按钮的点击事件,比PyAutoGUI找坐标可靠

    timer_id = root.after(30000, auto_click_no)  # 30000毫秒=30秒

    # 创建按钮
    btn_frame = ttk.Frame(popup)
    btn_frame.pack(pady=10)
    yes_btn = ttk.Button(btn_frame, text="Yes", command=on_yes_click)
    yes_btn.pack(side="left", padx=20)
    no_btn = ttk.Button(btn_frame, text="No", command=on_no_click)
    no_btn.pack(side="right", padx=20)

    root.mainloop()

# 启动程序
create_wake_check_popup()

关键改进点

  • 非阻塞弹窗:用Toplevel自定义弹窗,配合after()定时器实现超时逻辑,不会卡住程序主线程。
  • 避免固定坐标:直接调用按钮的invoke()方法触发点击,比PyAutoGUI依赖屏幕坐标更稳定(不同系统/分辨率下按钮位置会变)。
  • 定时器管理:用户手动点击按钮后,立即取消定时器,防止超时逻辑重复触发。
  • 弹窗置顶:设置-topmost属性确保弹窗不会被其他窗口遮挡,保证用户能看到。

如果一定要用PyAutoGUI模拟点击(不推荐),可以在auto_click_no()函数里替换成你的坐标点击代码,但要注意弹窗必须置顶且坐标准确:

def auto_click_no():
    pyautogui.moveTo(1026, 620, duration=0)
    pyautogui.click()

内容的提问来源于stack exchange,提问作者HuskWolfy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:15:52