EG/demo/test_gui_complete.py
2025-07-02 09:49:59 +08:00

311 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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()