-->

Capturing mouse events outside wx.Frame in Python

2019-06-23 23:10发布

问题:

In Python using wxPython, how can I set the transparency and size of a window based on the proximity of the mouse relative to the application's window, or frame?

Eg. similar to a hyperbolic zoom, or The Dock in MAC OS X? I am trying to achieve this effect with a png with transparency and a shaped window.

Any libraries or code snippets that do this would be great too. Thanks.

回答1:

Here's code to do it. Basically uses the approach mentioned by Infinity77. Tested on Windows. Works nicely!

import wx

MIN_ALPHA = 64
MAX_ALPHA = 255

class Frame(wx.Frame):
    def __init__(self):
        super(Frame, self).__init__(None)
        self.alpha = MAX_ALPHA
        self.SetTitle('Mouse Alpha')
        self.on_timer()
    def on_timer(self):
        x, y, w, h = self.GetRect()
        mx, my = wx.GetMousePosition()
        d1 = max(x - mx, mx - (x + w))
        d2 = max(y - my, my - (y + h))
        alpha = MAX_ALPHA - max(d1, d2)
        alpha = max(alpha, MIN_ALPHA)
        alpha = min(alpha, MAX_ALPHA)
        if alpha != self.alpha:
            self.SetTransparent(alpha)
            self.alpha = alpha
        wx.CallLater(20, self.on_timer)

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


回答2:

I don't think it can be done that easily if the mouse is outside the main frame. That said, you can always do the following:

1) Start a timer in your main frame and poll it every 50 milliseconds (or whatever suits you);

2) Once you poll it in your OnTimer event handler, check the mouse position via wx.GetMousePosition() (this will be in screen coordinates);

3) In the same OnTimer method, get the screen position of your frame, via frame.GetScreenPosition();

4) Compare the mouse position with the frame position (maybe using an euclidean distance calculation, or whatever suits you). Then you set your frame transparency accordingly to this distance (remember to put it fully opaque if the mouse is inside the frame rectangle).

I did just it for the fun of it, it shouldn't take more than 5 minutes to implement.

Hope this helps.

Andrea.