问题描述
我尝试将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()