370 lines
10 KiB
Markdown
370 lines
10 KiB
Markdown
# 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. 中文字体加载系统
|
||
|
||
在每个文件中添加了统一的字体加载函数:
|
||
|
||
```python
|
||
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 组件
|
||
```python
|
||
# ✅ 正确的方法
|
||
text = OnscreenText(
|
||
text="中文文本",
|
||
font=self.chinese_font if self.chinese_font else None
|
||
)
|
||
```
|
||
|
||
#### DirectButton 组件
|
||
```python
|
||
# ✅ 正确的方法(注意使用text_font参数)
|
||
button = DirectButton(
|
||
text="按钮文本",
|
||
text_font=self.chinese_font if self.chinese_font else None
|
||
)
|
||
```
|
||
|
||
#### DirectLabel 组件
|
||
```python
|
||
# ✅ 正确的方法
|
||
label = DirectLabel(
|
||
text="标签文本",
|
||
text_font=self.chinese_font if self.chinese_font else None
|
||
)
|
||
```
|
||
|
||
#### DirectCheckButton 组件
|
||
```python
|
||
# ✅ 正确的方法
|
||
checkbox = DirectCheckButton(
|
||
text="复选框文本",
|
||
text_font=self.chinese_font if self.chinese_font else None
|
||
)
|
||
```
|
||
|
||
#### DirectRadioButton 组件
|
||
```python
|
||
# ✅ 正确的方法
|
||
radio = DirectRadioButton(
|
||
text="单选按钮文本",
|
||
text_font=self.chinese_font if self.chinese_font else None
|
||
)
|
||
```
|
||
|
||
#### DirectOptionMenu 组件
|
||
```python
|
||
# ✅ 正确的方法
|
||
menu = DirectOptionMenu(
|
||
text="选项菜单",
|
||
text_font=self.chinese_font if self.chinese_font else None
|
||
)
|
||
```
|
||
|
||
### 3. 3D空间文本组件
|
||
|
||
#### TextNode(3D文本)
|
||
```python
|
||
# ✅ 正确的方法
|
||
text3d = TextNode('text-name')
|
||
text3d.setText("3D中文文本")
|
||
if self.chinese_font:
|
||
text3d.setFont(self.chinese_font)
|
||
```
|
||
|
||
### 4. 特殊修复
|
||
|
||
#### DirectRadioButton 回调函数修复
|
||
|
||
**问题:** `gui_test.py`中DirectRadioButton的回调函数参数不匹配
|
||
|
||
**修复前:**
|
||
```python
|
||
def onRadioButtonSelect(self, status): # ❌ 缺少参数
|
||
```
|
||
|
||
**修复后:**
|
||
```python
|
||
# 添加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)` |
|
||
|
||
## 🚀 测试验证
|
||
|
||
所有修复的文件都已通过测试:
|
||
|
||
```bash
|
||
# 测试基础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. **字体安装:** 确保系统已安装中文字体
|
||
```bash
|
||
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创建方法,添加坐标转换:
|
||
|
||
```python
|
||
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组件提供专门的编辑界面:
|
||
|
||
```python
|
||
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位置编辑:
|
||
|
||
```python
|
||
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 到 1(Panda3D标准)
|
||
- **转换比例**: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时的坐标建议
|
||
```python
|
||
# 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组件,包括按钮、标签和输入框。 |