Pygame:允许点击通过窗口

Posted

技术标签:

【中文标题】Pygame:允许点击通过窗口【英文标题】:Pygame: allow clicks to go through the window 【发布时间】:2016-09-07 01:44:00 【问题描述】:

我在 pygame 中制作了一个伪透明窗口,目的是显示各种信息,例如“HUD”

该脚本使用 PIL 抓取桌面图像并将其用作窗口的背景。

一个简单的版本:

import pygame as py
from ctypes import windll
import ImageGrab, Image

SetWindowPos = windll.user32.SetWindowPos

py.init()

def get_image():
    im = ImageGrab.grab((0,0,window_x,window_y))
    mode = im.mode
    size = im.size
    data = im.tobytes()
    im = py.image.fromstring(data,size,mode)
    return im

window_x = 1920
window_y = 100

background = py.Surface((window_x,window_y))
background.blit(get_image(),(0,0))

window_pos = (0,0)


screen = py.display.set_mode((window_x,window_y),py.HWSURFACE|py.NOFRAME)

SetWindowPos(py.display.get_wm_info()['window'],-1,0,0,0,0,0x0001)

clock = py.time.Clock()

done = False

while not done:
    for event in py.event.get():
        if event.type == py.QUIT:
            done = True
    screen.blit(background,(0,0))
    py.display.flip()
    clock.tick(30)

py.quit()

这会在屏幕顶部创建一个 Pygame 窗口。

我的问题是 Pygame 窗口阻止了任何鼠标与其下方的任何交互。

有没有办法让鼠标事件被忽略并“通过”窗口,例如单击 Pygame 窗口下方的桌面图标。

【问题讨论】:

您的目标操作系统是什么?在 Mac OS X、Windows、Linux 上有不同的方法。如果你能提到我可以尝试链接一段特定的代码。 我目前正在使用并优先考虑 Windows,但 Linux 解决方案也会有所帮助。 【参考方案1】:

你需要做一些额外的黑客攻击,这超出了 PyGame 给你的能力。应该可以将 PyGame 画布渲染到 Python 中的另一个窗口框架中,并尝试使用该库的高级功能来实现这一点。

在 Windows 中

一个例子是 wxWidgets。 As described in this thread,这听起来与您要实现的目标非常相似,用户设置了一个可以单击的窗口并且是透明的。

Also see this another *** Post 提到了如何在 C# 中处理命中测试。在此处发布该帖子中的代码:

protected override void WndProc(ref Message m)

    if (m.Msg == (int)WM_NCHITTEST)
        m.Result = (IntPtr)HTTRANSPARENT;
    else
        base.WndProc(ref m);

可以使用 win32 API 在 Python 中进行类似的测试。 This is a piece of Python code that does exactly this. 找到程序员为事件设置回调的部分(类似于win32con.WM_NCHITTEST: self.onChi,,其中self.onChi 是回调)。

我希望这能给你一个起点。我怀疑有什么现成的东西可以让你开箱即用,但这些应该会给你一些关于寻找什么的指示。

【讨论】:

谢谢,这很有帮助。提到的线程包含这一行:win32gui.SetLayeredWindowAttributes(hwnd, 0, 255, win32con.LWA_ALPHA),它被注释为处理“点击”的行。我从 py.display.get_wm_info()['window'] 获得了 pygame 窗口的句柄,但该行抛出错误:win32gui.SetLayeredWindowAttributes(hwnd, 0, 255, win32con.LWA_ALPHA) error: (87, 'SetLayeredWindowAttributes', 'The parameter is incorrect.'),有什么想法吗? 嗯,不是真的,但有一些想法:PyGame 窗口必须是***窗口,并确保它不是子窗口,另外,确保您从 pygame 获得的句柄是SetLayeredWindowAttributes 接受的正确类型。一旦我使用 Windows 机器,我会检查更多。

以上是关于Pygame:允许点击通过窗口的主要内容,如果未能解决你的问题,请参考以下文章

pygame学习记录 创建一个窗口

pygame学习记录 创建一个窗口

Pygame中完全透明的窗口?

有没有办法用 MOUSEBUTTONDOWN 事件关闭 pygame 窗口?

Pygame没有在按键时退出

Pygame没有暂停更新屏幕[重复]