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