EG/demo/test_qt_showbase.py
2025-12-12 16:16:15 +08:00

284 lines
10 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 -*-
"""
Qt环境ShowBase测试
使用ShowBase在独立窗口中验证GUI功能
"""
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 *
# 配置Panda3D
loadPrcFileData("", """
win-size 800 600
window-title ShowBase GUI Test
framebuffer-multisample 1
multisamples 2
""")
class ShowBaseGUITest(ShowBase):
def __init__(self):
ShowBase.__init__(self)
print("=== ShowBase GUI测试 ===")
# 设置背景色
self.setBackgroundColor(0.2, 0.2, 0.3)
# 调整相机位置
self.cam.setPos(0, -10, 5)
self.cam.lookAt(0, 0, 0)
# 初始化GUI元素列表
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
# 创建测试内容
self.createTestContent()
# 立即创建GUI元素
self.createGUIElements()
print("\n测试说明:")
print("这是使用ShowBase的独立窗口测试")
print("如果GUI元素正常显示说明主程序的GUI创建逻辑是正确的")
print("问题可能在于Qt集成部分")
def createTestContent(self):
"""创建测试内容"""
print("\n--- 创建3D测试内容 ---")
# 创建地面
cm = CardMaker("ground")
cm.setFrame(-10, 10, -10, 10)
ground = self.render.attachNewNode(cm.generate())
ground.setP(-90)
ground.setColor(0.5, 0.5, 0.5, 1)
# 创建一个立方体
cube = self.loader.loadModel("models/environment")
if not cube:
# 如果找不到内置模型,创建一个简单几何体
cm = CardMaker("test-cube")
cm.setFrame(-1, 1, -1, 1)
cube = self.render.attachNewNode(cm.generate())
cube.reparentTo(self.render)
cube.setPos(0, 5, 1)
cube.setColor(0.8, 0.2, 0.2, 1)
# 添加光照
alight = AmbientLight('alight')
alight.setColor((0.3, 0.3, 0.3, 1))
alnp = self.render.attachNewNode(alight)
self.render.setLight(alnp)
dlight = DirectionalLight('dlight')
dlight.setColor((0.8, 0.8, 0.8, 1))
dlnp = self.render.attachNewNode(dlight)
dlnp.setHpr(45, -45, 0)
self.render.setLight(dlnp)
print("3D内容创建完成")
def createGUIElements(self):
"""创建GUI元素"""
print("\n--- 创建GUI元素 ---")
# 创建标题
self.title = OnscreenText(
text="ShowBase 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
)
# 测试主程序中的GUI创建方法
print("开始创建各种GUI元素...")
# 按钮测试 - 使用不同的逻辑坐标
self.button1 = self.createGUIButton((0, 0, 0), "中心按钮", 0.08)
self.button2 = self.createGUIButton((-15, 0, 0), "左按钮", 0.08)
self.button3 = self.createGUIButton((15, 0, 0), "右按钮", 0.08)
self.button4 = self.createGUIButton((0, 0, 15), "上按钮", 0.08)
self.button5 = self.createGUIButton((0, 0, -15), "下按钮", 0.08)
# 标签测试
self.label1 = self.createGUILabel((0, 0, -25), "中心标签", 0.06)
self.label2 = self.createGUILabel((-20, 0, -10), "左标签", 0.06)
self.label3 = self.createGUILabel((20, 0, -10), "右标签", 0.06)
# 输入框测试
self.entry1 = self.createGUIEntry((0, 0, -35), "中心输入框", 0.05)
self.entry2 = self.createGUIEntry((-20, 0, -25), "左输入框", 0.05)
self.entry3 = self.createGUIEntry((20, 0, -25), "右输入框", 0.05)
# 3D文本测试
self.text3d1 = self.createGUI3DText((0, 5, 3), "主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"\nGUI创建完成总计: {len(self.gui_elements)} 个元素")
print("如果你能看到所有GUI元素说明修复是成功的")
# 复制主程序中的GUI创建方法
def createGUIButton(self, pos=(0, 0, 0), text="按钮", size=0.1):
"""创建2D GUI按钮"""
# 将3D坐标转换为2D屏幕坐标
gui_pos = (pos[0] * 0.1, 0, pos[2] * 0.1)
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} (逻辑位置: {pos}, 屏幕位置: {gui_pos})")
return button
def createGUILabel(self, pos=(0, 0, 0), text="标签", size=0.08):
"""创建2D GUI标签"""
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} (逻辑位置: {pos}, 屏幕位置: {gui_pos})")
return label
def createGUIEntry(self, pos=(0, 0, 0), placeholder="输入文本...", size=0.08):
"""创建2D GUI文本输入框"""
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} (逻辑位置: {pos}, 屏幕位置: {gui_pos})")
return entry
def createGUI3DText(self, pos=(0, 0, 0), text="3D文本", size=0.5):
"""创建3D空间文本"""
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)
self.gui_elements.append(textNodePath)
print(f"✓ 创建3D文本: {text} (世界位置: {pos})")
return textNodePath
def createGUIVirtualScreen(self, pos=(0, 0, 0), size=(2, 1), text="虚拟屏幕"):
"""创建3D虚拟屏幕"""
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)
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}'")
def main():
"""主函数"""
print("启动ShowBase GUI功能测试...")
print("这将在独立的Panda3D窗口中测试GUI功能")
# 创建并运行应用
app = ShowBaseGUITest()
app.run()
if __name__ == "__main__":
main()