解决Pyglet窗口任意位置拖动时的闪烁问题
解决Pyglet窗口任意区域拖动时的闪烁问题
问题原因
你当前的代码在拖动窗口时出现闪烁,核心问题出在on_mouse_drag事件的dx/dy参数上:这两个值是鼠标相对于窗口内部的偏移量,当你调用set_location移动窗口后,Pyglet会重新计算鼠标在窗口内的坐标,导致下一次on_mouse_drag触发时的dx/dy包含了窗口移动带来的额外偏移,最终窗口位置在两个状态间反复跳动,表现为闪烁。
解决方案
要解决这个问题,需要基于鼠标的全局屏幕坐标来计算窗口位置,而非依赖窗口内部的偏移量。具体步骤是:
- 鼠标按下时,记录鼠标相对于窗口左上角的偏移量(即鼠标在窗口内的位置到窗口左上角的距离)
- 拖动过程中,始终让窗口左上角保持在「当前鼠标屏幕坐标 - 之前记录的偏移量」的位置
修改后的代码如下:
import pyglet class Window(pyglet.window.Window): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.drag_offset = None # 存储鼠标相对于窗口左上角的偏移量 def on_mouse_press(self, x, y, buttons, modifiers): if buttons & pyglet.window.mouse.LEFT: # 计算鼠标按下时,与窗口左上角的偏移 win_x, win_y = self.get_location() mouse_x, mouse_y = self.get_mouse_position() self.drag_offset = (mouse_x - win_x, mouse_y - win_y) def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): if buttons & pyglet.window.mouse.LEFT and self.drag_offset: # 根据当前鼠标位置和偏移量,计算窗口新位置 mouse_x, mouse_y = self.get_mouse_position() self.set_location(mouse_x - self.drag_offset[0], mouse_y - self.drag_offset[1]) if __name__ == "__main__": win = Window(400, 300) pyglet.app.run()
关键改动说明
on_mouse_press:按下左键时,通过窗口位置和鼠标全局坐标的差值,记录鼠标相对于窗口的固定偏移on_mouse_drag:拖动时直接用鼠标当前全局坐标减去偏移量,得到窗口左上角的目标位置,完全避开了窗口移动对鼠标内部坐标的干扰,从根源上消除了闪烁
内容的提问来源于stack exchange,提问作者WhiteNight1357
相关产品推荐
相关产品推荐

