Tkinter:当试图点击离开时,窗口闪烁

2024-09-27 21:30:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着做这件事已经有一段时间了,但还没有想出办法。在

我有一个tkinter脚本,当一个按钮被按下时,它会创建一个弹出窗口。但是我不希望用户能够从这个窗口点击到以前创建的任何窗口。我有这个工作root.grab_集(),但是没有向用户指示他们必须停留在该窗口上。在

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模块创建的窗口时,如果您试图单击另一个窗口,则filedialogue窗口将保持在顶部,并有一个“闪烁”的动画,让用户知道他们不能单击离开。我有办法复制这个效果吗?浏览filedialogue的源代码对我来说并没有什么收获,谷歌搜索也没有。在


Tags: the用户self脚本objecttkinterrootwindow
2条回答

下面是一个Windows解决方案,它使用user32dll中的^{}。您需要向它传递一个^{}对象。grab_set确保弹出窗口保持焦点并禁用主窗口中的任何窗口小部件,使弹出窗口暂时性确保它始终位于主窗口的顶部。<Button-1>事件用于检查鼠标单击,winfo_containing检查是否单击了弹出窗口之外的其他窗口。然后我将焦点设置回弹出窗口,并在焦点处闪烁窗口(然后总是弹出窗口)。在

你需要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()

现在,只有在单击主窗口的主体时才会出现闪烁,所以单击标题栏只会将焦点返回到弹出窗口而不闪烁。要使它在这种情况下也能触发,可以尝试使用<FocusOut>事件,但必须确保它只在焦点转移到主窗口时发生,但由于使用了grab_set,所以它从来没有真正触发过。你可能想弄清楚,但现在它运行得很好。所以这并不完美,但我希望能有所帮助。在

我能想到的最简单的方法是使用事件和焦点命令以及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()

相关问题 更多 >

    热门问题