#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ GraphicsBuffer DirectGUI专门测试 验证DirectGUI在GraphicsBuffer中的行为 """ import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) import sys from direct.showbase.ShowBase import ShowBase from direct.gui.DirectGui import * from direct.gui.OnscreenText import OnscreenText from panda3d.core import * class GraphicsBufferGUITest(ShowBase): def __init__(self): ShowBase.__init__(self) print("=== GraphicsBuffer DirectGUI测试 ===") # 设置背景色 self.setBackgroundColor(0.2, 0.2, 0.3) # 创建一个GraphicsBuffer来模拟Qt环境 self.createGraphicsBuffer() # 在主窗口中创建GUI (作为对照) self.createMainWindowGUI() # 在GraphicsBuffer中创建GUI (测试目标) self.createBufferGUI() print("\n测试说明:") print("这个测试创建了GraphicsBuffer来模拟Qt环境") print("比较主窗口和GraphicsBuffer中DirectGUI的行为差异") def createGraphicsBuffer(self): """创建GraphicsBuffer""" print("\n--- 创建GraphicsBuffer ---") # 创建缓冲区 fbp = FrameBufferProperties() wp = WindowProperties.size(800, 600) wp.setUndecorated(True) self.buffer = self.graphicsEngine.makeOutput( self.pipe, "test-buffer", -100, # sort fbp, wp, GraphicsPipe.BFRequireWindow # flags ) if not self.buffer: print("❌ 创建GraphicsBuffer失败") return print(f"✓ GraphicsBuffer创建成功: {self.buffer}") print(f" 类型: {type(self.buffer)}") print(f" 大小: {self.buffer.getXSize()} x {self.buffer.getYSize()}") # 为缓冲区创建显示区域 self.bufferDR = self.buffer.makeDisplayRegion() print(f"✓ 显示区域创建: {self.bufferDR}") # 创建专用的2D相机给GraphicsBuffer self.bufferCamera2d = self.makeCamera2d(self.buffer) print(f"✓ 2D相机创建: {self.bufferCamera2d}") # 设置相机 self.bufferDR.setCamera(self.bufferCamera2d) # 获取render2d节点 - 这是关键 self.bufferRender2d = self.bufferCamera2d.getParent() print(f"✓ 缓冲区render2d: {self.bufferRender2d}") # 获取aspect2d节点 self.bufferAspect2d = self.bufferRender2d.find("**/aspect2d") if self.bufferAspect2d.isEmpty(): print("⚠️ 缓冲区中没有找到aspect2d,手动创建") self.bufferAspect2d = self.bufferRender2d.attachNewNode("aspect2d") else: print(f"✓ 缓冲区aspect2d: {self.bufferAspect2d}") def createMainWindowGUI(self): """在主窗口中创建GUI(对照组)""" print("\n--- 主窗口GUI(对照组)---") self.mainTitle = OnscreenText( text="主窗口GUI(正常)", pos=(-0.5, 0.8), scale=0.08, fg=(1, 1, 1, 1), align=TextNode.ACenter ) self.mainButton = DirectButton( text="主窗口按钮", pos=(-0.5, 0, 0.5), scale=0.1, frameColor=(0, 1, 0, 1), command=self.onMainButtonClick ) print(f"✓ 主窗口标题: {self.mainTitle}") print(f"✓ 主窗口按钮: {self.mainButton}") print(f" 按钮父节点: {self.mainButton.getParent()}") def createBufferGUI(self): """在GraphicsBuffer中创建GUI(测试组)""" print("\n--- GraphicsBuffer GUI(测试组)---") if not hasattr(self, 'bufferAspect2d'): print("❌ 缓冲区aspect2d不可用") return # 方法1: 直接在缓冲区的aspect2d下创建 try: self.bufferTitle = OnscreenText( text="缓冲区GUI(测试)", pos=(0.5, 0.8), scale=0.08, fg=(1, 1, 0, 1), align=TextNode.ACenter, parent=self.bufferAspect2d # 指定父节点 ) print(f"✓ 缓冲区标题: {self.bufferTitle}") print(f" 标题父节点: {self.bufferTitle.getParent()}") except Exception as e: print(f"❌ 缓冲区标题创建失败: {str(e)}") # 方法2: 创建DirectGUI组件并重新父化 try: self.bufferButton = DirectButton( text="缓冲区按钮", pos=(0.5, 0, 0.5), scale=0.1, frameColor=(1, 0, 0, 1), command=self.onBufferButtonClick ) # 重新父化到缓冲区的aspect2d self.bufferButton.reparentTo(self.bufferAspect2d) print(f"✓ 缓冲区按钮: {self.bufferButton}") print(f" 按钮父节点: {self.bufferButton.getParent()}") except Exception as e: print(f"❌ 缓冲区按钮创建失败: {str(e)}") # 方法3: 直接在bufferRender2d下创建TextNode try: textNode = TextNode('buffer-direct-text') textNode.setText("直接创建的文本") textNode.setAlign(TextNode.ACenter) self.bufferDirectText = self.bufferRender2d.attachNewNode(textNode) self.bufferDirectText.setPos(0.5, 0, 0) self.bufferDirectText.setScale(0.08) self.bufferDirectText.setColor(0, 1, 1, 1) print(f"✓ 缓冲区直接文本: {self.bufferDirectText}") except Exception as e: print(f"❌ 缓冲区直接文本创建失败: {str(e)}") # 检查缓冲区状态 self.checkBufferState() def checkBufferState(self): """检查缓冲区状态""" print("\n--- 缓冲区状态检查 ---") if hasattr(self, 'buffer'): print(f"缓冲区有效: {self.buffer.isValid()}") print(f"缓冲区激活: {self.buffer.isActive()}") print(f"显示区域数量: {self.buffer.getNumDisplayRegions()}") for i in range(self.buffer.getNumDisplayRegions()): dr = self.buffer.getDisplayRegion(i) print(f" 显示区域 {i}: {dr}") print(f" 相机: {dr.getCamera()}") print(f" 激活: {dr.isActive()}") if hasattr(self, 'bufferAspect2d'): print(f"缓冲区aspect2d子节点数: {self.bufferAspect2d.getNumChildren()}") for i in range(self.bufferAspect2d.getNumChildren()): child = self.bufferAspect2d.getChild(i) print(f" 子节点 {i}: {child}") def onMainButtonClick(self): """主窗口按钮点击""" print("🟢 主窗口按钮被点击!") def onBufferButtonClick(self): """缓冲区按钮点击""" print("🔴 缓冲区按钮被点击!") def main(): """主函数""" print("启动GraphicsBuffer DirectGUI专门测试...") app = GraphicsBufferGUITest() app.run() if __name__ == "__main__": main()