【问题标题】:Tkinter window won't get focus because of pyHook mouse LeftDown function由于 pyHook 鼠标 LeftDown 功能,Tkinter 窗口不会获得焦点
【发布时间】:2017-05-21 05:00:21
【问题描述】:

所以我试图通过使用 pyHook 感知鼠标左键单击来打开一个 tkinter 窗口,并且我希望新打开的窗口能够获得焦点。问题是,无论我尝试什么焦点方法,当前窗口都将始终保留焦点,而不是焦点切换到新的 tkinter 窗口。代码如下:

from tkinter import *
import pyHook
import pythoncom        

def open_GUI():
root = Tk()
root.title('test')
entry_box = Entry(root, font=("Calibri", 11))
entry_box.focus()
entry_box.pack(fill=X, side=RIGHT, expand=True)
root.after(1, lambda: root.focus_set())
root.mainloop()
return True


def MouseLeftDown_Func(event):
    print('mouse')
    open_GUI()
    return True


def KeyDown_Func(event):
    print('key')
    return True


hooks_manager = pyHook.HookManager()
hooks_manager.KeyDown = KeyDown_Func
hooks_manager.MouseLeftDown = MouseLeftDown_Func
hooks_manager.HookKeyboard()
hooks_manager.HookMouse()
pythoncom.PumpMessages()

我认为问题在于,当我左键单击当前窗口时,焦点优先于最近单击的窗口(当前窗口),并且任何调用 tkinter 窗口焦点的命令都会被忽略。

有谁知道左键单击后如何将焦点切换到新的 tkinter 窗口?

【问题讨论】:

    标签: tkinter pyhook pythoncom


    【解决方案1】:

    在导入 pyhook 后,我用这个替换了另一个解决方案。这有点复杂,但是当您试图窃取键盘焦点时,就会发生这种情况。可能有更简单的方法来做到这一点。此解决方案的关键是告诉应用程序在创建条目之前将根窗口设置为前台,但在事件中。如果您不使用 Windows,也有 Linux 解决方案。

    from ctypes import Structure, c_ulong, byref, c_char_p, windll
    from tkinter import *
    import pyHook
    import pythoncom
    
    class POINT(Structure):
        _fields_ = [("x", c_ulong), ("y", c_ulong)]
    
    def open_GUI():
        root = Tk()
        root.title('test')
        root.update()
        root.after(20, lambda r=root: createEntry(r))
        root.mainloop()
        return True
    
    def setRootForeground(root):
        # Get window coordinates
        x = root.winfo_rootx() + 1
        y = root.winfo_rooty() + 1
        # Move the mouse cursor to x,y
        windll.user32.SetCursorPos(x, y)
        # Get the pointer coordinates into a Windows-compatible format
        pt = POINT()
        windll.user32.GetCursorPos(byref(pt))
        # Get the window handle under the pointer -- should be root.
        hwnd = windll.user32.WindowFromPoint(pt)
        # Make it the foreground window
        windll.user32.SetForegroundWindow(hwnd)
    
    def createEntry(root):
        setRootForeground(root)
        root.focus_set()
        entry_box = Entry(root, font=("Calibri", 11))
        entry_box.pack(fill=X, side=RIGHT, expand=True)
        entry_box.focus_set()
    

    【讨论】:

    • 嗨罗恩,谢谢你的回复。我已经在没有 pyhook 的情况下尝试过它,并且焦点工作正常。我的主要问题是当我导入 pyhook 并使用鼠标左键打开窗口时。您可以尝试导入 pyhook 的代码并让我知道您的想法吗?非常感谢,阿里
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    相关资源
    最近更新 更多