311 lines
12 KiB
Python
311 lines
12 KiB
Python
#!/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() |