使用WXPYTHON为单独的程序提供右键单击上下文菜单



我在格式化这个问题的标题时遇到了麻烦,因为我不确定我是否会以正确的方式处理这个问题,所以让我解释一下。

我想尝试将右键单击上下文菜单添加到我没有源代码的现有程序中。wxpython通常是我的选择框架。我认为有几种方法可以做到这一点:

1)创建一个透明的wx.frame,该帧与现有程序的顶部绑定并位于拦截鼠标事件的顶部。如果我这样做,我不确定是否可以将鼠标事件传递到基础窗口。我喜欢此选项,因为它可以在覆盖层中添加更多有用的信息。

2)创建一个无头的程序,该程序在全球截取右键单击事件,并在满足某些条件时在指针位置产生上下文菜单。根据我到目前为止所做的研究,如果不连续进行小鼠位置进行轮询,这似乎并不可能。

我想念什么?有一个更优雅的解决方案吗?这甚至可以使用Python?

编辑:我有一个部分概念证明工作,看起来像这样:

import wx
import win32gui
import win32api
import win32con
class POC_Frame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, id=wx.ID_ANY, title='POC', pos=(0,0), size=wx.Size(500, 500), style=wx.DEFAULT_FRAME_STYLE)
        self.ToggleWindowStyle(wx.STAY_ON_TOP)
        extendedStyleSettings = win32gui.GetWindowLong(self.GetHandle(), win32con.GWL_EXSTYLE)
        win32gui.SetWindowLong(self.GetHandle(), win32con.GWL_EXSTYLE,
                               extendedStyleSettings | win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT)
        win32gui.SetLayeredWindowAttributes(self.GetHandle(), win32api.RGB(0,0,0), 100, win32con.LWA_ALPHA)
        self.Bind(wx.EVT_RIGHT_DOWN, self.onRightDown)
        self.Bind(wx.EVT_RIGHT_UP, self.onRightUp)
        self.CaptureMouse()
    def onRightDown(self, event):
        print(event)
    def onRightUp(self, event):
        print(event)
app = wx.App(False)
MainFrame = POC_Frame(None)
MainFrame.Show()
app.MainLoop()

这似乎可以正常工作,因为它将右键单击事件传递到基础窗口,同时仍然识别它们,但仅一次就可以。一旦失去焦点,它就会停止工作,而我没有试图将重点恢复到它似乎有效。

我一直在用pyhook而不是wx钩上全局鼠标和键盘事件的好运。这是一个简单的例子:

import pyHook
import pyHook.cpyHook  # ensure its included by cx-freeze

class ClickCatcher:
    def __init__(self):
        self.hm = None
        self._is_running = True
        self._is_cleaned_up = False
        self._is_quitting = False
        self.set_hooks()
    # this is only necessary when not using wx
    # def send_quit_message(self):
    #     import ctypes
    #     win32con_WM_QUIT = 18
    #     ctypes.windll.user32.PostThreadMessageW(self.pump_message_thread.ident, win32con_WM_QUIT, 0, 0)
    def __del__(self):
        self.quit()
    def quit(self):
        if not self._is_running:
            return
        self._is_quitting = True
        self._is_running = False
        if self.hm:
            # self.hm.UnhookKeyboard()
            self.hm.UnhookMouse()
        # self.send_quit_message()
        self._is_cleaned_up = True
    def set_hooks(self):
        self._is_running = True
        self._is_cleaned_up = False
        self.hm = pyHook.HookManager()
        self.hm.MouseRightUp = self.on_right_click
        # self.hm.HookKeyboard()
        self.hm.HookMouse()

    def on_right_click(self):
        # create your menu here
        pass

如果您不使用wx,则必须使用pythoncom.PumpMessages将鼠标和键盘事件推向程序,但是App.Mainloop()完成了同样的事情(如果您使用pumpmessages和mainloop一起使用,则大约一半的事件不会推入您的程序)。

创建一个wx.menu非常容易。您可以使用wx.GetMousePosition()

找到鼠标坐标。

最新更新