Ubuntu平台下如何让Pygame窗口始终或条件保持置顶?
在Ubuntu上实现Pygame窗口始终置顶或条件性置顶
一、始终保持窗口置顶
在Ubuntu的X11环境下,Pygame本身没有直接提供置顶窗口的API,需要通过操作X11窗口属性来实现。我们可以借助python-xlib库修改窗口的_NET_WM_STATE属性,将窗口设置为始终置顶。
步骤1:安装依赖
先安装python-xlib库:
pip install python-xlib
步骤2:修改代码实现置顶
修改你的Pygame代码,添加窗口置顶逻辑:
# Simple pygame program import pygame from Xlib import X, display # Import and initialize the pygame library pygame.init() # Set up the drawing window window_width = 500 window_height = 500 window_size = (window_width, window_height) surface = pygame.display.set_mode(window_size, pygame.RESIZABLE) # 获取Pygame窗口的X11窗口ID window_id = pygame.display.get_wm_info()['window'] # 连接到X显示服务 d = display.Display() x_window = d.create_resource_object('window', window_id) # 设置窗口始终置顶的函数 def set_window_topmost(topmost): net_wm_state = d.intern_atom('_NET_WM_STATE') net_wm_state_above = d.intern_atom('_NET_WM_STATE_ABOVE') if topmost: # 添加置顶属性 x_window.change_property(net_wm_state, X.ATOM_ATOM, 32, [net_wm_state_above]) else: # 移除置顶属性 x_window.change_property(net_wm_state, X.ATOM_ATOM, 32, []) # 同步到X显示服务 d.sync() # 初始化设置为置顶 set_window_topmost(True) # Run until the user asks to quit running = True circle_center = (int(surface.get_width()/2), int(surface.get_height()/2)) circle_radius = 75 while running: # Fill the background with white surface.fill((255, 255, 255)) # Draw a solid blue circle in the center pygame.draw.circle(surface, (0, 0, 255), circle_center, circle_radius) # Flip the display pygame.display.flip() # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.VIDEORESIZE: surface = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE) circle_center = (int(surface.get_width()/2), int(surface.get_height()/2)) # Done! Time to quit. pygame.quit()
二、条件性置顶(点击特定区域切换)
如果需要点击窗口内的特定区域(比如示例中的蓝色圆圈)来切换置顶状态,可以添加鼠标点击检测逻辑,维护一个置顶状态变量:
修改后的完整代码:
# Simple pygame program import pygame from Xlib import X, display # Import and initialize the pygame library pygame.init() # Set up the drawing window window_width = 500 window_height = 500 window_size = (window_width, window_height) surface = pygame.display.set_mode(window_size, pygame.RESIZABLE) # 获取Pygame窗口的X11窗口ID window_id = pygame.display.get_wm_info()['window'] d = display.Display() x_window = d.create_resource_object('window', window_id) # 置顶状态标记 is_topmost = False # 设置窗口置顶状态的函数 def set_window_topmost(topmost): global is_topmost is_topmost = topmost net_wm_state = d.intern_atom('_NET_WM_STATE') net_wm_state_above = d.intern_atom('_NET_WM_STATE_ABOVE') if topmost: x_window.change_property(net_wm_state, X.ATOM_ATOM, 32, [net_wm_state_above]) else: x_window.change_property(net_wm_state, X.ATOM_ATOM, 32, []) d.sync() # Run until the user asks to quit running = True circle_center = (int(surface.get_width()/2), int(surface.get_height()/2)) circle_radius = 75 while running: # Fill the background with white surface.fill((255, 255, 255)) # Draw a solid blue circle in the center pygame.draw.circle(surface, (0, 0, 255), circle_center, circle_radius) # Flip the display pygame.display.flip() # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.VIDEORESIZE: surface = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE) circle_center = (int(surface.get_width()/2), int(surface.get_height()/2)) # 检测鼠标点击事件 if event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() # 计算鼠标到圆心的距离,判断是否点击圆圈区域 distance = ((mouse_pos[0] - circle_center[0])**2 + (mouse_pos[1] - circle_center[1])**2)**0.5 if distance <= circle_radius: set_window_topmost(not is_topmost) # Done! Time to quit. pygame.quit()
说明
- 上述代码利用X11的
_NET_WM_STATE_ABOVE属性实现窗口置顶,这是Ubuntu等X11桌面环境的标准窗口属性,兼容性良好。 - 条件性置顶通过计算鼠标点击位置与目标区域的距离触发状态切换,你可以根据需求修改触发区域的判断逻辑(比如换成按钮、特定矩形区域等)。
内容的提问来源于stack exchange,提问作者Zubair Adil
相关产品推荐
相关产品推荐

