Ursina引擎中能否将两个独立窗口设为父子窗口并联动?
在Ursina引擎中实现多窗口联动与层级锁定
结论
Ursina本身没有原生支持窗口父子绑定的API,但可以通过底层依赖的Pyglet库结合自定义事件逻辑,模拟实现两个窗口的联动(位置、激活状态同步)以及子窗口始终前置的效果。
实现步骤与代码示例
1. 初始化双窗口
Ursina默认只创建一个主窗口,第二个窗口需要直接基于Pyglet的Window类创建(Ursina的Window本质是对Pyglet窗口的封装):
from ursina import * import pyglet # 初始化主Ursina窗口 app = Ursina() window.title = "主窗口" window.size = (800, 600) # 创建独立子窗口 child_window = pyglet.window.Window( width=300, height=200, title="子窗口", always_on_top=False # 先不强制置顶,通过事件控制层级 )
2. 绑定窗口位置联动
监听主窗口的移动事件,同步子窗口的位置,保持固定相对偏移:
def sync_child_window_position(x, y): # 让子窗口固定在主窗口右上方,偏移20px child_x = x + window.width + 20 child_y = y - 20 # 注意Pyglet的窗口坐标原点在屏幕左上角 child_window.set_location(child_x, child_y) # 绑定主窗口的移动事件(window.win是底层Pyglet窗口对象) window.win.on_move = sync_child_window_position # 初始同步位置 sync_child_window_position(window.x, window.y)
3. 锁定子窗口层级与激活联动
确保主窗口被激活时,子窗口也自动前置,保持整体联动:
def on_main_window_activate(): # 激活子窗口,使其置于前台 child_window.activate() window.win.on_activate = on_main_window_activate # 绑定子窗口激活事件,同步激活主窗口(可选) @child_window.event def on_activate(): window.win.activate()
4. 同步窗口生命周期
确保关闭任意一个窗口时,另一个也随之关闭:
def on_main_window_close(): child_window.close() window.win.on_close = on_main_window_close @child_window.event def on_close(): application.quit()
5. 整合事件循环
由于Ursina运行自己的事件循环,需要在update函数中处理子窗口的事件分发:
def update(): # 处理子窗口的Pyglet事件 child_window.dispatch_events() app.run()
注意事项
- 上述实现是模拟联动效果,并非系统级的父子窗口(如Windows平台的
WS_CHILD窗口样式)。如果需要真正的系统级父子窗口,需调用平台特定API(如Windows的win32api)修改窗口属性,复杂度更高。 - 不同操作系统的窗口管理行为可能存在差异,测试时需适配目标平台。
- 若子窗口需要渲染Ursina内容,不能直接用Pyglet窗口,需额外创建Ursina的
Window实例并手动管理其上下文,这会增加复杂度。
内容的提问来源于stack exchange,提问作者Alex Krakowiak
相关产品推荐
相关产品推荐

