#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 完整的GUI功能测试 测试主程序中的所有GUI创建和编辑功能 """ import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) import sys import builtins from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QMenu, QAction, QDockWidget, QTreeWidget, QListWidget, QWidget, QVBoxLayout, QTreeWidgetItem, QLabel, QLineEdit, QFormLayout, QDoubleSpinBox, QScrollArea, QTreeView, QInputDialog, QFileDialog, QMessageBox, QDialog, QGroupBox, QHBoxLayout, QPushButton, QDialogButtonBox) from PyQt5.QtCore import Qt, QDir, QUrl from PyQt5.QtGui import QDrag, QPainter, QPixmap from QPanda3D.QPanda3DWidget import QPanda3DWidget from QPanda3D.Panda3DWorld import Panda3DWorld from direct.gui.DirectGui import * from direct.gui.OnscreenText import OnscreenText from panda3d.core import * import os # 简化的世界类,专门用于GUI测试 class GUITestWorld(Panda3DWorld): def __init__(self): super().__init__() # 设置相机位置 self.cam.setPos(0, -10, 5) self.cam.lookAt(0, 0, 0) # 设置背景色 self.setBackgroundColor(0.2, 0.2, 0.3) self.gui_elements = [] # 尝试加载中文字体 try: self.chinese_font = self.loader.loadFont('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc') if not self.chinese_font: print("警告: 无法加载中文字体,将使用默认字体") except: print("警告: 无法加载中文字体,将使用默认字体") self.chinese_font = None # 延迟创建GUI元素,确保所有系统都已初始化 self.taskMgr.doMethodLater(0.1, self.createTestGUIElements, "create-gui") def createTestGUIElements(self, task=None): """创建测试用的GUI元素""" print("\n=== 开始创建测试GUI元素 ===") # 测试2D GUI组件 print("创建2D GUI组件...") # 按钮测试 - 不同位置 self.button1 = self.createGUIButton((0, 0, 0), "中心按钮", 0.08) self.button2 = self.createGUIButton((-5, 0, 0), "左侧按钮", 0.08) self.button3 = self.createGUIButton((5, 0, 0), "右侧按钮", 0.08) self.button4 = self.createGUIButton((0, 0, 5), "上方按钮", 0.08) self.button5 = self.createGUIButton((0, 0, -5), "下方按钮", 0.08) # 标签测试 self.label1 = self.createGUILabel((0, 0, -8), "测试标签", 0.06) self.label2 = self.createGUILabel((-8, 0, 0), "左标签", 0.06) self.label3 = self.createGUILabel((8, 0, 0), "右标签", 0.06) # 输入框测试 self.entry1 = self.createGUIEntry((0, 0, -12), "中心输入框", 0.05) self.entry2 = self.createGUIEntry((-8, 0, -8), "左输入框", 0.05) # 测试3D GUI组件 print("创建3D GUI组件...") # 3D文本测试 self.text3d1 = self.createGUI3DText((0, 5, 2), "3D测试文本", 0.5) self.text3d2 = self.createGUI3DText((-3, 3, 1), "左3D文本", 0.3) self.text3d3 = self.createGUI3DText((3, 3, 1), "右3D文本", 0.3) # 虚拟屏幕测试 self.screen1 = self.createGUIVirtualScreen((0, 8, 0), (3, 2), "主虚拟屏幕") self.screen2 = self.createGUIVirtualScreen((-5, 5, 2), (2, 1), "左屏幕") self.screen3 = self.createGUIVirtualScreen((5, 5, 2), (2, 1), "右屏幕") print(f"=== GUI元素创建完成,总计: {len(self.gui_elements)} 个 ===\n") # 验证每个元素的显示状态 self.verifyGUIElements() # 添加标题 self.title = OnscreenText( text="Qt集成GUI测试", pos=(0, 0.9), scale=0.08, fg=(1, 1, 1, 1), align=TextNode.ACenter, font=self.chinese_font if self.chinese_font else None ) return task.done if task else None def verifyGUIElements(self): """验证GUI元素的显示状态""" print("=== 验证GUI元素显示状态 ===") for i, element in enumerate(self.gui_elements): gui_type = element.getTag("gui_type") if hasattr(element, 'getTag') else "unknown" gui_text = element.getTag("gui_text") if hasattr(element, 'getTag') else "unnamed" if hasattr(element, 'getPos'): pos = element.getPos() print(f"{i+1}. {gui_type}: '{gui_text}' 位置: {pos}") else: print(f"{i+1}. {gui_type}: '{gui_text}' (无位置信息)") print("=== 验证完成 ===\n") # 复制主程序中的GUI创建方法 def createGUIButton(self, pos=(0, 0, 0), text="按钮", size=0.1): """创建2D GUI按钮""" from direct.gui.DirectGui import DirectButton # 将3D坐标转换为2D屏幕坐标 gui_pos = (pos[0] * 0.1, 0, pos[2] * 0.1) try: button = DirectButton( text=text, pos=gui_pos, scale=size, command=self.onGUIButtonClick, extraArgs=[f"button_{len(self.gui_elements)}"], frameColor=(0.2, 0.6, 0.8, 1), text_font=self.chinese_font if self.chinese_font else None, rolloverSound=None, clickSound=None ) button.setTag("gui_type", "button") button.setTag("gui_id", f"button_{len(self.gui_elements)}") button.setTag("gui_text", text) self.gui_elements.append(button) print(f"✓ 创建GUI按钮成功: {text} 在位置 {gui_pos}") print(f" 按钮节点: {button}") print(f" 按钮父节点: {button.getParent()}") # 验证按钮是否真的可见 if hasattr(button, 'isHidden'): print(f" 按钮隐藏状态: {button.isHidden()}") return button except Exception as e: print(f"✗ 创建GUI按钮失败: {text} - 错误: {str(e)}") return None def createGUILabel(self, pos=(0, 0, 0), text="标签", size=0.08): """创建2D GUI标签""" from direct.gui.DirectGui import DirectLabel gui_pos = (pos[0] * 0.1, 0, pos[2] * 0.1) label = DirectLabel( text=text, pos=gui_pos, scale=size, frameColor=(0, 0, 0, 0), text_fg=(1, 1, 1, 1), text_font=self.chinese_font if self.chinese_font else None ) label.setTag("gui_type", "label") label.setTag("gui_id", f"label_{len(self.gui_elements)}") label.setTag("gui_text", text) self.gui_elements.append(label) print(f"创建GUI标签: {text} 在位置 {gui_pos}") return label def createGUIEntry(self, pos=(0, 0, 0), placeholder="输入文本...", size=0.08): """创建2D GUI文本输入框""" from direct.gui.DirectGui import DirectEntry gui_pos = (pos[0] * 0.1, 0, pos[2] * 0.1) entry = DirectEntry( text="", pos=gui_pos, scale=size, command=self.onGUIEntrySubmit, extraArgs=[f"entry_{len(self.gui_elements)}"], initialText=placeholder, numLines=1, width=12, focus=0 ) entry.setTag("gui_type", "entry") entry.setTag("gui_id", f"entry_{len(self.gui_elements)}") entry.setTag("gui_placeholder", placeholder) self.gui_elements.append(entry) print(f"创建GUI输入框: {placeholder} 在位置 {gui_pos}") return entry def createGUI3DText(self, pos=(0, 0, 0), text="3D文本", size=0.5): """创建3D空间文本""" from panda3d.core import TextNode textNode = TextNode(f'3d-text-{len(self.gui_elements)}') textNode.setText(text) textNode.setAlign(TextNode.ACenter) if self.chinese_font: textNode.setFont(self.chinese_font) textNodePath = self.render.attachNewNode(textNode) textNodePath.setPos(*pos) textNodePath.setScale(size) textNodePath.setColor(1, 1, 0, 1) textNodePath.setBillboardAxis() textNodePath.setTag("gui_type", "3d_text") textNodePath.setTag("gui_id", f"3d_text_{len(self.gui_elements)}") textNodePath.setTag("gui_text", text) textNodePath.setTag("is_gui_element", "1") self.gui_elements.append(textNodePath) print(f"创建3D文本: {text} 在位置 {pos}") return textNodePath def createGUIVirtualScreen(self, pos=(0, 0, 0), size=(2, 1), text="虚拟屏幕"): """创建3D虚拟屏幕""" from panda3d.core import CardMaker, TransparencyAttrib, TextNode cm = CardMaker(f"virtual-screen-{len(self.gui_elements)}") cm.setFrame(-size[0]/2, size[0]/2, -size[1]/2, size[1]/2) virtualScreen = self.render.attachNewNode(cm.generate()) virtualScreen.setPos(*pos) virtualScreen.setColor(0.2, 0.2, 0.2, 0.8) virtualScreen.setTransparency(TransparencyAttrib.MAlpha) screenText = TextNode(f'screen-text-{len(self.gui_elements)}') screenText.setText(text) screenText.setAlign(TextNode.ACenter) if self.chinese_font: screenText.setFont(self.chinese_font) screenTextNP = virtualScreen.attachNewNode(screenText) screenTextNP.setPos(0, 0.01, 0) screenTextNP.setScale(0.3) screenTextNP.setColor(0, 1, 0, 1) virtualScreen.setTag("gui_type", "virtual_screen") virtualScreen.setTag("gui_id", f"virtual_screen_{len(self.gui_elements)}") virtualScreen.setTag("gui_text", text) virtualScreen.setTag("is_gui_element", "1") self.gui_elements.append(virtualScreen) print(f"创建虚拟屏幕: {text} 在位置 {pos}") return virtualScreen def onGUIButtonClick(self, button_id): """GUI按钮点击事件处理""" print(f"✓ GUI按钮点击测试成功: {button_id}") def onGUIEntrySubmit(self, text, entry_id): """GUI输入框提交事件处理""" print(f"✓ GUI输入框提交测试成功: {entry_id} = {text}") class GUITestWidget(QPanda3DWidget): def __init__(self, world, parent=None): super().__init__(world, parent) self.world = world def testMainGUIFeatures(): """测试主程序的GUI功能""" print("=== 开始测试主程序GUI功能 ===") app = QApplication(sys.argv) # 创建测试世界 world = GUITestWorld() # 创建主窗口 mainWindow = QMainWindow() mainWindow.setWindowTitle("GUI功能完整测试") mainWindow.setGeometry(100, 100, 1200, 800) # 创建Panda3D部件 pandaWidget = GUITestWidget(world) mainWindow.setCentralWidget(pandaWidget) # 显示窗口 mainWindow.show() print("测试窗口已打开,你应该能看到:") print("- 5个不同位置的2D按钮(可点击)") print("- 3个不同位置的2D标签") print("- 2个不同位置的2D输入框(可输入)") print("- 3个不同位置的3D文本(面向相机)") print("- 3个不同位置的3D虚拟屏幕") print("如果所有元素都可见,说明修复成功!") # 运行应用 return app.exec_() if __name__ == "__main__": exit_code = testMainGUIFeatures()