1
0
forked from Rowland/EG
EG/demo/COMPLETE_FIXES_SUMMARY.md
2025-07-02 09:49:59 +08:00

10 KiB
Raw Blame History

PANDA3D GUI 中文显示问题完整修复总结

🎯 修复概览

本次修复解决了PANDA3D GUI系统中中文字符显示问题涉及5个测试文件的全面更新。

📋 修复清单

已修复的文件

文件名 修复状态 主要修复内容
chinese_gui_test.py 完成 创建专门的中文字体测试程序
gui_test.py 完成 修复DirectRadioButton回调函数+所有组件中文支持
simple_gui_test.py 完成 添加中文字体加载和按钮支持
basic_gui_demo.py 完成 基础组件中文字体支持
gui_3d_demo.py 完成 2D/3D文本组件中文字体支持

🔧 具体修复内容

1. 中文字体加载系统

在每个文件中添加了统一的字体加载函数:

def loadChineseFont(self):
    """尝试加载中文字体"""
    import os
    font_paths = [
        '/usr/share/fonts/truetype/wqy/wqy-microhei.ttc',
        '/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc',
        '/usr/share/fonts/truetype/arphic/ukai.ttc',
        '/usr/share/fonts/truetype/arphic/uming.ttc',
    ]
    
    for font_path in font_paths:
        if os.path.exists(font_path):
            try:
                font = self.loader.loadFont(font_path)
                if font:
                    return font
            except:
                continue
    return None

2. GUI组件字体设置

OnscreenText 组件

# ✅ 正确的方法
text = OnscreenText(
    text="中文文本",
    font=self.chinese_font if self.chinese_font else None
)

DirectButton 组件

# ✅ 正确的方法注意使用text_font参数
button = DirectButton(
    text="按钮文本",
    text_font=self.chinese_font if self.chinese_font else None
)

DirectLabel 组件

# ✅ 正确的方法
label = DirectLabel(
    text="标签文本",
    text_font=self.chinese_font if self.chinese_font else None
)

DirectCheckButton 组件

# ✅ 正确的方法
checkbox = DirectCheckButton(
    text="复选框文本",
    text_font=self.chinese_font if self.chinese_font else None
)

DirectRadioButton 组件

# ✅ 正确的方法
radio = DirectRadioButton(
    text="单选按钮文本",
    text_font=self.chinese_font if self.chinese_font else None
)

DirectOptionMenu 组件

# ✅ 正确的方法
menu = DirectOptionMenu(
    text="选项菜单",
    text_font=self.chinese_font if self.chinese_font else None
)

3. 3D空间文本组件

TextNode3D文本

# ✅ 正确的方法
text3d = TextNode('text-name')
text3d.setText("3D中文文本")
if self.chinese_font:
    text3d.setFont(self.chinese_font)

4. 特殊修复

DirectRadioButton 回调函数修复

问题: gui_test.py中DirectRadioButton的回调函数参数不匹配

修复前:

def onRadioButtonSelect(self, status):  # ❌ 缺少参数

修复后:

# 添加extraArgs参数
radio = DirectRadioButton(
    command=self.onRadioButtonSelect,
    extraArgs=[i],  # 传递索引参数
)

# 修改回调函数
def onRadioButtonSelect(self, index, status):  # ✅ 正确的参数

🎨 字体组件对应表

GUI组件类型 字体参数名 示例
OnscreenText font OnscreenText(font=chinese_font)
DirectButton text_font DirectButton(text_font=chinese_font)
DirectLabel text_font DirectLabel(text_font=chinese_font)
DirectCheckButton text_font DirectCheckButton(text_font=chinese_font)
DirectRadioButton text_font DirectRadioButton(text_font=chinese_font)
DirectOptionMenu text_font DirectOptionMenu(text_font=chinese_font)
TextNode setFont() textnode.setFont(chinese_font)

🚀 测试验证

所有修复的文件都已通过测试:

# 测试基础GUI
python3 basic_gui_demo.py

# 测试简单GUI
python3 simple_gui_test.py

# 测试完整GUI功能
python3 gui_test.py

# 测试中文字体专门功能
python3 chinese_gui_test.py

# 测试3D空间GUI
python3 gui_3d_demo.py

📚 使用建议

  1. 字体安装: 确保系统已安装中文字体

    sudo apt-get install fonts-wqy-microhei fonts-wqy-zenhei
    
  2. 字体检测: 运行程序时查看控制台输出,确认字体加载状态

  3. 回退机制: 如果中文字体加载失败,程序会自动使用默认字体

  4. 组件选择: 根据需要选择合适的示例程序开始学习

修复成果

  • 5个测试文件全部支持中文显示
  • 涵盖所有主要DirectGUI组件
  • 支持2D和3D空间文本
  • 提供字体加载状态反馈
  • 包含完整的使用示例和说明

现在PANDA3D GUI系统可以完美显示中文字符了🎉

完整的GUI修复总结报告

问题诊断

用户报告的问题

test.py 程序中3D文本和虚拟屏幕能正常显示但其他的GUI组件按钮、标签、输入框看不见。

根本原因分析

通过深入分析发现,问题的根本原因是坐标系统不匹配

  1. 3D GUI组件3D文本、虚拟屏幕使用世界坐标系统

    • 坐标范围:任意实数范围
    • 挂载到:render 节点下
    • 位置世界3D空间中的绝对位置
  2. 2D GUI组件(按钮、标签、输入框)使用屏幕坐标系统

    • 坐标范围:-1 到 1 的标准化坐标
    • 挂载到:render2d/aspect2d 节点下
    • 位置:屏幕空间中的相对位置

具体问题

当传入 (5, 0, 0) 这样的坐标时:

  • 3D组件正常显示世界坐标系可以接受任意值
  • 2D组件超出屏幕范围而不可见屏幕坐标系只接受-1到1的值

解决方案实施

1. 修改GUI创建方法

test.py 中修改了三个2D GUI创建方法添加坐标转换

def createGUIButton(self, pos=(0, 0, 0), text="按钮", size=0.1):
    # 将3D逻辑坐标转换为2D屏幕坐标
    gui_pos = (pos[0] * 0.1, 0, pos[2] * 0.1)
    # ... 其余代码保持不变

转换公式:屏幕坐标 = 逻辑坐标 × 0.1

2. 优化属性面板

修改了 updateGUIPropertyPanel() 方法为2D GUI组件提供专门的编辑界面

def updateGUIPropertyPanel(self, gui_element):
    gui_type = gui_element.getTag("gui_type")
    
    if gui_type in ["button", "label", "entry"]:
        # 2D GUI使用逻辑坐标编辑用户友好
        logical_x = pos.getX() / 0.1  # 反向转换
        logical_z = pos.getZ() / 0.1
        # 显示实际屏幕坐标(只读)
    else:
        # 3D GUI继续使用世界坐标编辑

3. 添加专用编辑方法

新增了 editGUI2DPosition() 方法处理2D GUI位置编辑

def editGUI2DPosition(self, gui_element, axis, value):
    if axis == "x":
        new_screen_x = value * 0.1  # 逻辑坐标转屏幕坐标
        gui_element.setPos(new_screen_x, current_pos.getY(), current_pos.getZ())

测试验证

创建的测试脚本

  1. test_2d_gui_fix.py - ShowBase环境基础测试

    • 运行成功所有GUI组件可见可交互
    • 验证了修复逻辑的正确性
  2. test_gui_complete.py - Qt集成环境完整测试

    • GUI元素创建成功
    • ⚠️ 在Qt环境中可能存在渲染显示问题
  3. test_simple_gui.py - 简化验证测试

    • 验证了修复逻辑正确
  4. test_qt_fix.py - Qt环境专门测试

    • GUI元素正确创建并添加到scene graph
    • ⚠️ Qt环境显示可能有问题
  5. test_qt_debug.py - Qt深度诊断

    • 🔍 发现Qt环境创建的是GraphicsBuffer而不是GraphicsWindow
    • 🔍 这是导致渲染问题的根本原因
  6. test_qt_showbase.py - ShowBase独立验证

    • 在独立窗口中完全正常显示

测试结果总结

ShowBase环境

  • 状态:完全成功
  • 表现所有2D GUI组件正常显示和交互
  • 验证:修复方案完全有效

Qt集成环境 ⚠️

  • 状态GUI元素创建成功但渲染可能有问题
  • 原因Qt环境中Panda3D创建的是Buffer而不是Window
  • 影响可能需要额外的Qt-Panda3D集成调试

技术细节

坐标转换系统

  • 逻辑坐标范围-50 到 50用户友好
  • 屏幕坐标范围-1 到 1Panda3D标准
  • 转换比例0.1(可调整)

用户界面改进

  • 2D GUI组件编辑使用逻辑坐标直观
  • 显示实际屏幕坐标(调试用)
  • 3D GUI组件继续使用世界坐标
  • 添加了坐标类型提示

场景图结构

render2d/
├── aspect2d/
│   ├── DirectButton (2D GUI按钮)
│   ├── DirectLabel (2D GUI标签)
│   └── DirectEntry (2D GUI输入框)
└── camera2d

render/
├── 3d-text-* (3D文本)
├── virtual-screen-* (虚拟屏幕)
└── camera

使用建议

1. 在主程序中使用

修复已应用到主程序 test.py所有2D GUI组件现在应该正常显示。

2. 创建GUI时的坐标建议

# 2D GUI组件 - 使用逻辑坐标(-50到50范围
world.createGUIButton((0, 0, 0), "中心按钮")      # 屏幕中心
world.createGUIButton((-20, 0, 0), "左侧按钮")     # 屏幕左侧
world.createGUIButton((20, 0, 0), "右侧按钮")      # 屏幕右侧

# 3D GUI组件 - 使用世界坐标
world.createGUI3DText((0, 5, 2), "3D文本")        # 世界空间位置
world.createGUIVirtualScreen((3, 8, 0), "屏幕")   # 世界空间位置

3. 属性面板编辑

  • 2D GUI编辑逻辑坐标-50到50系统自动转换
  • 3D GUI直接编辑世界坐标
  • 实际屏幕坐标以只读方式显示

后续建议

1. Qt集成优化

如果需要在Qt环境中获得完美的渲染效果可能需要

  • 深入研究Qt-Panda3D集成机制
  • 考虑使用不同的Qt集成方案
  • 或使用独立的Panda3D窗口

2. 功能扩展

  • 可以考虑添加更多坐标系统支持
  • 增加GUI组件的更多属性编辑
  • 提供坐标转换的可视化工具

3. 测试完善

  • 添加更多边界条件测试
  • 测试更复杂的GUI布局
  • 验证不同分辨率下的表现

结论

主要问题已解决2D GUI组件的坐标转换修复完成在ShowBase环境中测试完全成功。

Qt环境状态GUI元素创建正确但可能需要额外的渲染调试。

修复效果用户现在应该能够在主程序中看到所有GUI组件包括按钮、标签和输入框。