当 _tkinter window 不活动时,如何让不活动计时器在 tkinter 中工作?

How to get inactivity timer to work in tkniter when tkinter window is not active?

当 tkinter window 被撤回或不在其他 windows 之上时,我无法获得计时器(循环或任何东西)运行。它的功能就像一个小屏幕保护程序,启动程序,显示图标,单击显示全屏图像出现,如果三次单击它消失并返回系统托盘。所有这些都有效,但是 after 方法中的计时器仅在显示 window 时才有效,我希望它在未显示时有效,以便它可以在一段时间不活动后显示它(测试 10 秒) .

当 tkinter window 未显示时,如何让不活动计时器工作?

from tkinter import *
from ctypes import Structure, windll, c_uint, sizeof, byref
import time
import pystray
from PIL import Image, ImageTk

class LASTINPUTINFO(Structure):
    _fields_ = [
        ('cbSize', c_uint),
        ('dwTime', c_uint),
    ]

def get_idle_duration():
    lastInputInfo = LASTINPUTINFO()
    lastInputInfo.cbSize = sizeof(lastInputInfo)
    windll.user32.GetLastInputInfo(byref(lastInputInfo))
    millis = windll.kernel32.GetTickCount() - lastInputInfo.dwTime
    return millis / 1000.0

class FS_Display:
    def __init__(self):
        self.root = Tk()
        self.root.title("FS Display")
        self.root.bind("<Triple-1>", self.end_fullscreen)
        self.root.bind("<Escape>", self.end_fullscreen)
        self.root.protocol('WM_DELETE_WINDOW', self.end_fullscreen)
        self.end_fullscreen()

    def end_fullscreen(self, event=None):
        self.root.withdraw()
        self.image = Image.open("favicon.png")
        self.menu = (pystray.MenuItem('Quit', self.quit), pystray.MenuItem('Show', self.show_fullscreen))
        self.icon = pystray.Icon("name", self.image, "FS Display", self.menu)
        self.icon.run()

    def show_fullscreen(self, event=None):
        self.root.attributes("-fullscreen", True)
        self.icon.stop()
        self.root.deiconify()

    def quit(self, event=None):
        self.icon.stop()
        self.root.destroy()

    def idle_check(self, event=None):
        GetLastInputInfo = int(get_idle_duration())
        print(GetLastInputInfo)
        if GetLastInputInfo == 10:
            self.show_fullscreen()
        self.root.after(1000, self.idle_check)

if __name__ == '__main__':
    fs = FS_Display()
    main_image = Image.open("D:black_background.png")
    photo = ImageTk.PhotoImage(main_image)
    Label(fs.root, image=photo).pack()
    fs.root.after(1000, fs.idle_check)
    fs.root.mainloop()

定时器和后代码确实起作用了。 psytray 代码 icon.run() 阻塞直到 icon.stop()。您可以给 icon.run() 一个回调,允许它 运行 一个计时器。缺点是图标菜单选项在回调循环中不起作用。