微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

wxPython,使用pyxhook时如何从另一个应用程序中夺走焦点?

如何解决wxPython,使用pyxhook时如何从另一个应用程序中夺走焦点?

我尝试将pyxhook与wxPython一起使用。程序应该做的是隐藏或最小化窗口时,当用户按下“ R_Control”时,即使另一个应用程序仍在焦点上,也应该显示wxPython窗口并设置焦点。但是,相反,它只是通过在任务栏中闪烁来完成RequestUserAttention的操作。我尝试使用Raise()Restore(),但仍然无法使用。这是代码的简化版本

import wx,pyxhook

class Frame(wx.Frame):
    def __init__(self,parent):
        wx.Frame.__init__(self,name='',parent=parent,title='test')
        self.panel = wx.Panel(self,wx.ID_ANY)
        self.text_input = wx.TextCtrl(self.panel)
        self.moduleSizer = wx.BoxSizer(wx.VERTICAL)
        self.panel.SetSizer(self.moduleSizer)
        self.moduleSizer.Add(self.text_input,flag=wx.ALIGN_CENTER)
        self.text_input.Bind(wx.EVT_KEY_DOWN,self.onKeyDown)
        self.moduleSizer.Fit(self)
        self.text_input.SetFocus()

    def onKeyDown(self,event):
        if event.GetKeyCode() == wx.WXK_ESCAPE: self.Hide()
        event.Skip()

class HookMan(pyxhook.HookManager):
    def __init__(self,frame,master=None):
        pyxhook.HookManager.__init__(self,master)
        self.frame = frame
        self.KeyDown = self.key_down
        self.HookKeyboard()

    def key_down(self,event):
        if event.Key == 'Control_R':
            self.frame.Show()

if __name__ == '__main__':
    app = wx.App()
    frame = Frame(None)
    hookman = HookMan(frame)
    hookman.start()
    frame.Show()
    app.MainLoop()

我已经在TkInter上尝试过了,而且效果很好。 root.deconify()只需将窗口置于焦点上。如何在wxPython中重新创建此行为?

import pyxhook
import tkinter as tk

class Root(tk.Tk):
    def __init__(self,master=None):
        tk.Tk.__init__(self,master)
        self.title('test')
        self.text_input = tk.Entry(self)
        self.text_input.pack()
        self.bind("<Escape>",self.minimize)

    def minimize(self,event):
        self.withdraw()

class HookMan(pyxhook.HookManager):
    def __init__(self,event):
        if event.Key == 'Control_R':
            self.frame.deiconify()

if __name__ == '__main__':
    root = Root()
    hookman = HookMan(root)
    hookman.start()
    root.text_input.focus_set()
    root.mainloop()

解决方法

为记录起见,您提交的代码(至少在带有wx 4.1.0的Linux上)确实有效。该窗口已在现有窗口下复活。
通过使用SetWindowStyle并重新调整对pyxhook的调用,我们可以使此代码正常运行。

import wx
import pyxhook

class Frame(wx.Frame):
    def __init__(self,parent):
        wx.Frame.__init__(self,name='',parent=parent,title='test')
        self.SetWindowStyle(wx.STAY_ON_TOP)
        self.panel = wx.Panel(self,wx.ID_ANY)
        self.text_input = wx.TextCtrl(self.panel)
        self.moduleSizer = wx.BoxSizer(wx.VERTICAL)
        self.panel.SetSizer(self.moduleSizer)
        self.moduleSizer.Add(self.text_input,flag=wx.ALIGN_CENTER)
        self.text_input.Bind(wx.EVT_KEY_DOWN,self.onKeyDown)
        self.Bind(wx.EVT_CLOSE,self.onExit)
        self.moduleSizer.Fit(self)
        self.text_input.SetFocus()
        self.hookman = HookMan(self)
        self.hookman.start()

    def onKeyDown(self,event):
        if event.GetKeyCode() == wx.WXK_ESCAPE:
            self.Hide()
        event.Skip()

    def onExit(self,event):
        self.hookman.cancel()
        self.hookman.join()
        self.Destroy()

class HookMan(pyxhook.HookManager):
    def __init__(self,parent,master=None):
        pyxhook.HookManager.__init__(self,master)
        self.frame = parent
        self.KeyDown = self.key_down

    def key_down(self,event):
        if event.Key == 'Control_R':
            self.frame.Show()
    
    def close(self):
        self.close()

if __name__ == '__main__':
    app = wx.App()
    frame = Frame(None)
    frame.Show()
    app.MainLoop()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。