Tkinter - 几秒钟后销毁窗口,除非检测到特定事件

时间:2018-04-04 23:08:10

标签: python tkinter

我正在写一个python脚本,每当我在i3窗口管理器中的不同窗口之间改变焦点时,使用Tkinter和i3ipc显示一个窗口。对于那些不知道那是什么的人,忽略那部分,我从中使用的只是一个功能,以获得我确定正在工作的焦点窗口的名称。我将发布以下代码。

#/usr/bin/env python

import i3ipc
import tkinter as tk

window_width = 150
window_height = 50

i3 = i3ipc.Connection()

root = tk.Tk()
root.withdraw()

current_window = None


# This function gets the name of the focused window.
def find_focused():
    focused = i3.get_tree().find_focused()
    window_name = focused.window_class
    return window_name


def create_new(root):
    global current_window
    if current_window is not None:
        current_window.destroy()
    current_window = tk.Toplevel(root)
    return current_window


def kill(root, window):
    root.quit()
    window.after(450, window.destroy())
    window.update()


"""
This is the closests I came to a solution (in my mind)

def eliminate(root, window):
    window.destroy()
    root.update()

def alternative_kill(root, window):
    window.after(450, lambda: eliminate(root, window))
    root.quit()
"""


def show_window(i3, e):

    print("ciclo")

    window_name = find_focused()

    window = create_new(root)
    window.overrideredirect(True)

    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    x = (screen_width/2) - (window_width/2)
    y = (screen_height/2) - (window_height/2)

    window.geometry("%dx%d+%d+%d" % (window_width, window_height, x, y))

    canvas = tk.Canvas(window)
    canvas.pack()
    canvas.create_text(window_width/2, window_height/2, text=window_name)

    window.after(50, lambda: kill(root, window))
    # alternatively, I'd call alternative_kill instead of this
    root.mainloop()


i3.on("window::focus", show_window)

i3.main()

这是我的问题。使用当前的代码实现,当我切换焦点时,会出现一个带有名称的窗口,并在450ms后消失。但是,如果我快速多次改变焦点(快于450毫秒),由于每个窗口需要被摧毁450毫秒并且要创建一个新窗口,因此它们的名称显示滞后。所以,我需要一些东西来破坏窗口并在焦点事件发生后立即显示一个新窗口,否则在450ms后将其销毁。

我已尝试使用 alternative_kill 切换 kill 功能(请参阅代码)。我以为我可以使用root.quit()退出mainloop,使其准备好接收更多事件,同时调用消除来销毁窗口和 root.update()展示它。显然,这不起作用,并且当运行该代码时,窗口仅在第一次焦点更改后显示并且它停止工作(如同,程序继续运行但显然没有收到进一步的事件)。

编辑:重申一下,我的目标是:在窗口出现后450ms消除窗口,除非同时发生事件(焦点更改),在这种情况下应立即销毁窗口并重新打开窗口应该出现。

0 个答案:

没有答案