Tkinter:Window 尝试点击离开时闪烁
Tkinter: Window flash when attempting to click away
我已经尝试这样做一段时间了,但还没有想出办法。
我有一个 tkinter 脚本,它会在按下按钮时创建一个弹出窗口 window。但是,我不希望用户能够从这个 window 单击到任何以前创建的 windows。我已经使用 root.grab_set() 进行了此操作,但是没有向用户表明他们必须留在那个 window 上。
class popup(object):
def __init__(self, parent):
self.root=Toplevel(parent)
self.root.grab_set() #prevents the user clicking on the parent window
#But the window doesnt 'flash' when an attempt to click away is made
例如,当您有一个由 filedialogue 模块创建的 window 时,如果您尝试单击另一个 window,则 filedialogue window 会停留在顶部并有一个 'flashing' 动画让用户知道他们不能点击离开。有什么办法可以重现这种效果吗?通过 filedialogue 的来源对我来说并没有取得成果,Google 搜索也没有。
我能想到的最简单的方法是使用事件和焦点命令,以及 windows bell
命令:
#!python3
import tkinter as tk
class popup(object):
def __init__(self, parent):
self.root=tk.Toplevel(parent)
self.root.title("Popup")
self.root.bind("<FocusOut>", self.Alarm)
def Alarm(self, event):
self.root.focus_force()
self.root.bell()
main = tk.Tk()
main.title("Main")
pop = popup(main)
main.mainloop()
这是 Windows 的解决方案,它使用 FlashWindowEx
from the user32
dll. You need to pass a FLASHWINFO
object。 grab_set
确保弹出窗口 window 保持焦点并禁用主要 window 中的任何小部件,使弹出窗口瞬态确保它始终位于主窗口之上。 <Button-1>
事件用于检查鼠标单击,winfo_containing
检查是否单击弹出窗口之外的另一个 window。然后,我将焦点设置回弹出窗口并使 window 闪烁(然后始终是弹出窗口)。
您需要 pywin32 才能使用它。
import Tkinter as tk
from ctypes import *
import win32con
class popup(object):
def __init__(self, parent):
self.parent = parent
self.root=tk.Toplevel(self.parent)
self.root.title("Popup")
self.root.grab_set()
self.root.transient(self.parent)
self.root.bind("<Button-1>", self.flash)
def flash(self, event):
if self.root.winfo_containing(event.x_root, event.y_root)!=self.root:
self.root.focus_set()
number_of_flashes = 5
flash_time = 80
info = FLASHWINFO(0,
windll.user32.GetForegroundWindow(),
win32con.FLASHW_ALL,
number_of_flashes,
flash_time)
info.cbSize = sizeof(info)
windll.user32.FlashWindowEx(byref(info))
class FLASHWINFO(Structure):
_fields_ = [('cbSize', c_uint),
('hwnd', c_uint),
('dwFlags', c_uint),
('uCount', c_uint),
('dwTimeout', c_uint)]
main = tk.Tk()
main.title("Main")
pop = popup(main)
main.mainloop()
现在,只有点击主window的body时才会出现闪现,所以点击标题栏只是returns弹出的焦点不会闪现.要在发生这种情况时也触发它,您可以尝试使用 <FocusOut>
事件,但您必须确保它仅在焦点传递到主 window 时发生,但自从grab_set
被使用。您可能想弄清楚这一点,但就目前而言,它运行良好。所以它并不完美,但我希望它能有所帮助。
我已经尝试这样做一段时间了,但还没有想出办法。
我有一个 tkinter 脚本,它会在按下按钮时创建一个弹出窗口 window。但是,我不希望用户能够从这个 window 单击到任何以前创建的 windows。我已经使用 root.grab_set() 进行了此操作,但是没有向用户表明他们必须留在那个 window 上。
class popup(object):
def __init__(self, parent):
self.root=Toplevel(parent)
self.root.grab_set() #prevents the user clicking on the parent window
#But the window doesnt 'flash' when an attempt to click away is made
例如,当您有一个由 filedialogue 模块创建的 window 时,如果您尝试单击另一个 window,则 filedialogue window 会停留在顶部并有一个 'flashing' 动画让用户知道他们不能点击离开。有什么办法可以重现这种效果吗?通过 filedialogue 的来源对我来说并没有取得成果,Google 搜索也没有。
我能想到的最简单的方法是使用事件和焦点命令,以及 windows bell
命令:
#!python3
import tkinter as tk
class popup(object):
def __init__(self, parent):
self.root=tk.Toplevel(parent)
self.root.title("Popup")
self.root.bind("<FocusOut>", self.Alarm)
def Alarm(self, event):
self.root.focus_force()
self.root.bell()
main = tk.Tk()
main.title("Main")
pop = popup(main)
main.mainloop()
这是 Windows 的解决方案,它使用 FlashWindowEx
from the user32
dll. You need to pass a FLASHWINFO
object。 grab_set
确保弹出窗口 window 保持焦点并禁用主要 window 中的任何小部件,使弹出窗口瞬态确保它始终位于主窗口之上。 <Button-1>
事件用于检查鼠标单击,winfo_containing
检查是否单击弹出窗口之外的另一个 window。然后,我将焦点设置回弹出窗口并使 window 闪烁(然后始终是弹出窗口)。
您需要 pywin32 才能使用它。
import Tkinter as tk
from ctypes import *
import win32con
class popup(object):
def __init__(self, parent):
self.parent = parent
self.root=tk.Toplevel(self.parent)
self.root.title("Popup")
self.root.grab_set()
self.root.transient(self.parent)
self.root.bind("<Button-1>", self.flash)
def flash(self, event):
if self.root.winfo_containing(event.x_root, event.y_root)!=self.root:
self.root.focus_set()
number_of_flashes = 5
flash_time = 80
info = FLASHWINFO(0,
windll.user32.GetForegroundWindow(),
win32con.FLASHW_ALL,
number_of_flashes,
flash_time)
info.cbSize = sizeof(info)
windll.user32.FlashWindowEx(byref(info))
class FLASHWINFO(Structure):
_fields_ = [('cbSize', c_uint),
('hwnd', c_uint),
('dwFlags', c_uint),
('uCount', c_uint),
('dwTimeout', c_uint)]
main = tk.Tk()
main.title("Main")
pop = popup(main)
main.mainloop()
现在,只有点击主window的body时才会出现闪现,所以点击标题栏只是returns弹出的焦点不会闪现.要在发生这种情况时也触发它,您可以尝试使用 <FocusOut>
事件,但您必须确保它仅在焦点传递到主 window 时发生,但自从grab_set
被使用。您可能想弄清楚这一点,但就目前而言,它运行良好。所以它并不完美,但我希望它能有所帮助。