EG/demo/test_qt_fix_v2.py
2025-07-02 09:49:59 +08:00

338 lines
12 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环境渲染修复版本
解决Qt集成环境中的渲染问题
"""
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLabel
from PyQt5.QtCore import Qt
from PyQt5.QtOpenGL import QOpenGLWidget
from direct.showbase.ShowBase import ShowBase
from direct.gui.DirectGui import *
from direct.gui.OnscreenText import OnscreenText
from panda3d.core import *
import os
# 强制配置Panda3D使用OpenGL
loadPrcFileData("", """
win-size 800 600
window-title Qt Fixed Test
framebuffer-multisample 1
multisamples 2
prefer-parasite-buffer false
""")
class QtFixedWorld(ShowBase):
def __init__(self):
ShowBase.__init__(self)
print("=== Qt修复版本世界初始化 ===")
# 设置背景色
self.setBackgroundColor(0.2, 0.2, 0.3)
print("背景色设置完成")
# 调整相机位置
self.cam.setPos(0, -10, 5)
self.cam.lookAt(0, 0, 0)
# 检查基本状态
print(f"窗口类型: {type(self.win)}")
print(f"图形引擎: {self.graphicsEngine}")
print(f"窗口大小: {self.win.getXSize()} x {self.win.getYSize()}")
# 初始化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.taskMgr.doMethodLater(0.5, self.createGUIElements, "create-gui")
def createTestContent(self):
"""创建测试内容"""
print("\n--- 创建测试内容 ---")
# 创建3D几何体
from panda3d.core import CardMaker
cm = CardMaker("test-plane")
cm.setFrame(-2, 2, -2, 2)
self.testPlane = self.render.attachNewNode(cm.generate())
self.testPlane.setPos(0, 5, 0)
self.testPlane.setColor(0.8, 0.2, 0.2, 1) # 红色
# 创建3D文本
textNode = TextNode('3d-text')
textNode.setText("3D Test Content")
textNode.setAlign(TextNode.ACenter)
if self.chinese_font:
textNode.setFont(self.chinese_font)
self.text3D = self.render.attachNewNode(textNode)
self.text3D.setPos(0, 3, 2)
self.text3D.setScale(0.5)
self.text3D.setColor(1, 1, 0, 1)
self.text3D.setBillboardAxis()
# 添加光照
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, task=None):
"""创建GUI元素"""
print("\n--- 创建GUI元素 ---")
# 创建屏幕标题
self.title = OnscreenText(
text="Qt环境修复测试",
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
)
print("屏幕标题创建完成")
# 测试主程序中的GUI创建方法
try:
# 按钮测试
self.button1 = self.createGUIButton((0, 0, 0), "中心按钮", 0.08)
self.button2 = self.createGUIButton((-10, 0, 0), "左按钮", 0.08)
self.button3 = self.createGUIButton((10, 0, 0), "右按钮", 0.08)
# 标签测试
self.label1 = self.createGUILabel((0, 0, -10), "测试标签", 0.06)
self.label2 = self.createGUILabel((-10, 0, -5), "左标签", 0.06)
# 输入框测试
self.entry1 = self.createGUIEntry((10, 0, -5), "输入框", 0.05)
# 3D文本测试
self.text3d1 = self.createGUI3DText((0, 5, 3), "3D文本测试", 0.5)
self.text3d2 = self.createGUI3DText((-3, 3, 1), "左3D文本", 0.3)
# 虚拟屏幕测试
self.screen1 = self.createGUIVirtualScreen((3, 8, 0), (2, 1), "虚拟屏幕")
print(f"GUI创建完成总计: {len(self.gui_elements)} 个元素")
except Exception as e:
print(f"GUI创建失败: {str(e)}")
return task.done if task else None
# 复制主程序中的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} 在屏幕位置 {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} 在屏幕位置 {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} 在屏幕位置 {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}")
class QtFixedWidget(QOpenGLWidget):
"""使用QOpenGLWidget的Panda3D部件"""
def __init__(self, world, parent=None):
super().__init__(parent)
self.world = world
self.setMinimumSize(800, 600)
print("Qt OpenGL部件创建完成")
def paintGL(self):
"""OpenGL绘制函数"""
if self.world and hasattr(self.world, 'graphicsEngine'):
self.world.graphicsEngine.renderFrame()
def main():
"""主函数"""
print("启动Qt环境修复测试...")
app = QApplication(sys.argv)
# 创建主窗口
mainWindow = QMainWindow()
mainWindow.setWindowTitle("Qt环境修复测试")
mainWindow.setGeometry(100, 100, 800, 600)
# 创建布局和容器
centralWidget = QWidget()
layout = QVBoxLayout(centralWidget)
# 添加状态标签
statusLabel = QLabel("Qt环境修复测试 - 应该能看到GUI元素")
statusLabel.setAlignment(Qt.AlignCenter)
statusLabel.setStyleSheet("background-color: lightgreen; padding: 10px; color: black;")
layout.addWidget(statusLabel)
# 创建修复版本的世界
world = QtFixedWorld()
# 创建OpenGL部件
openglWidget = QtFixedWidget(world)
layout.addWidget(openglWidget)
mainWindow.setCentralWidget(centralWidget)
# 显示窗口
mainWindow.show()
print("修复版本窗口已显示")
print("应该能看到:")
print("- 红色的3D平面")
print("- 黄色的3D文本")
print("- 多个2D GUI按钮蓝色")
print("- 2D GUI标签白色文字")
print("- 2D GUI输入框")
print("- 3D虚拟屏幕")
# 运行应用
return app.exec_()
if __name__ == "__main__":
exit_code = main()