【问题标题】:Tkinter see through window not affected by mouse clicksTkinter 透视窗口不受鼠标点击影响
【发布时间】:2015-06-10 02:42:40
【问题描述】:

我目前正在通过发送鼠标和击键命令使用 python 控制游戏。我想做的是在游戏上方放置一个透明的 Tkinter 窗口,以提供一些信息,例如鼠标位置和像素颜色。

我熟悉更改窗口的 alpha 属性以使其透明,但不知道如何始终将该窗口保持在前面并让鼠标点击穿过它。

我目前控制游戏的方法包括在某些位置截取屏幕截图并分析颜色内容。我还需要一些方法来做到这一点,而不会干扰 Tkinter 窗口。

Pyscreenshot 用于截图 win32api用于点击

谢谢, 亚历克

【问题讨论】:

    标签: python tkinter controls mouse alpha-transparency


    【解决方案1】:

    您可以使用win32gui 模块的SetWindowLong 功能。如果您想要一个透明的点击窗口,您必须在我们的窗口中应用GWL_EXSTYLE。因此,您需要 Window 的窗口句柄。

    hwnd = win32gui.FindWindow(None, "Your window title") # Getting window handle
    # hwnd = root.winfo_id() getting hwnd with Tkinter windows
    # hwnd = root.GetHandle() getting hwnd with wx windows
    lExStyle = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
    lExStyle |=  win32con.WS_EX_TRANSPARENT | win32con.WS_EX_LAYERED
    win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE , lExStyle )
    

    如果您想通过 winapi 更改窗口的透明度,请使用SetLayeredWindowAttributes

    编辑:覆盖始终在顶部的透明窗口的示例代码,它通过点击。它获取当前的桌面图像并创建一个透明的叠加层,因此您可以享受您的桌面背景图像。

    from win32api import GetSystemMetrics
    import win32con
    import win32gui
    import wx
    
    
    def scale_bitmap(bitmap, width, height):
        image = wx.ImageFromBitmap(bitmap)
        image = image.Scale(width, height, wx.IMAGE_QUALITY_HIGH)
        result = wx.BitmapFromImage(image)
        return result
    
    app = wx.App()
    trans = 50
    # create a window/frame, no parent, -1 is default ID
    # change the size of the frame to fit the backgound images
    frame1 = wx.Frame(None, -1, "KEA", style=wx.CLIP_CHILDREN | wx.STAY_ON_TOP)
    # create the class instance
    frame1.ShowFullScreen(True)
    image_file = win32gui.SystemParametersInfo(win32con.SPI_GETDESKWALLPAPER,0,0)
    bmp1 = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
    bmp1 = scale_bitmap(bmp1,GetSystemMetrics(1)*1.5,GetSystemMetrics(1))
    bitmap1 = wx.StaticBitmap(frame1, -1, bmp1, (-100, 0))
    hwnd = frame1.GetHandle()
     
    extendedStyleSettings = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
    win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, extendedStyleSettings  | win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT)
    win32gui.SetLayeredWindowAttributes(hwnd, 0, 255, win32con.LWA_ALPHA)
     
    frame1.SetTransparent(trans)
    
    
    def onKeyDown(e):
        global trans
        key = e.GetKeyCode()
        if  key==wx.WXK_UP:
            print trans
            trans+=10
            if trans >255:
                trans = 255
        elif key==wx.WXK_DOWN:
            print trans
            trans-=10
            if trans < 0:
                trans = 0
        try:
            win32gui.SetLayeredWindowAttributes(hwnd, 0, trans, win32con.LWA_ALPHA)
        except:
            pass
    frame1.Bind(wx.EVT_KEY_DOWN, onKeyDown)
    
    app.MainLoop()
    

    您可以使用向上/向下箭头键动态更改透明度。 请注意,windowframe 是使用 'wx' 创建的,但也应与 tkinter 一起使用。

    随意使用代码。

    【讨论】:

    • 这是否只允许鼠标点击传递到同一 tk 实例中的其他窗口?我之所以问,是因为我将此应用到了我的根窗口,并且我无法单击或拖动其他窗口(例如 Chrome)。
    • 这应该确实有效。我编写了一个小脚本,将我的桌面背景图像作为透明的最顶层窗口放置在所有其他窗口之上。这按预期工作,所有点击都通过并且拖放也有效。
    • 但你也可以尝试处理WM_NCHITTEST并返回HTNOWHERE
    • 好吧,如果我不知道您的代码,很难提供有用的帮助...我建议您使用可重现的代码创建一个问题
    • @PSSolanki 自从我接触 pyhton 以来已经有很长时间了,但是我编写了一个能够满足您需求的小应用程序。注意它的 wxpython 和 pyhton 2.7。我想我使用 wx 是因为 tk 在图像方面遇到了一些问题......但它很久以前才能正确记住
    猜你喜欢
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多