1.UI更新

This commit is contained in:
陈横 2025-10-19 23:05:56 +08:00
parent b386818f76
commit a4e5d834db
14 changed files with 1483 additions and 716 deletions

54
.gitignore vendored
View File

@ -1,3 +1,57 @@
__pycache__/
*.pyc
.idea/
【模板】模型及算法与功能对应清单.docx
【模板】GY知识-产品模块架构及功能清单和主要应用场景说明.docx
1.json
2.json
3.json
4.json
6.json
功能清单.md
模型及算法与功能对应清单(完整版).md
维修系统使用说明.md
audio_demo_config.json
create_test_audio.py
demo_universal_dialog.py
Dock按钮样式统一说明.md
Dock面板标题样式线完成说明.md
exam_result_20250926_004454.json
exam_result_20250926_010628.json
exam_result_20250926_011746.json
exam_result_20250926_090330.json
exam_result_20250926_111756.json
exam_test_config.json
Figma布局优化说明.md
Figma设计分析与菜单栏优化文档.md
Figma样式优化完成说明.md
manual_tools_config.json
pm.txt
simple_menubar_test.py
test_audio.py
test_basic_audio.py
test_exam_tool_error.py
test_full_audio_playback.py
test_menu_visibility.py
test_mode_selection.py
test_mp3_audio.py
test_pygame_audio.py
test_score_config.py
test_simple_audio.py
tool_test_config.json
UI设计文档.md
UniversalMessageDialog使用说明.md
.codex/settings/kiroCodex-settings.json
data/projects.json
RenderPipelineFile/config/daytime.yaml
Resources/audio/README.md
Resources/model/a.glb
Resources/model/b.glb
Resources/model/c.glb
Resources/model/JQB_auto_converted.glb
Resources/model/Untitled.glb
Resources/models/Women_1.glb
Subjects/test_maintenance_config.json
Resources/models/Women_1.glb
Resources/models/Women_1.glb
Resources/models/Women_1.glb

File diff suppressed because one or more lines are too long

0
Resources/a Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

BIN
icons/success_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

BIN
icons/warning_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

8
new/project.json Normal file
View File

@ -0,0 +1,8 @@
{
"name": "new",
"path": "D:\\PythonProject\\CH_EG\\EG\\new",
"created_at": "2025-09-09 16:47:27",
"last_modified": "2025-09-11 09:28:24",
"version": "1.0.0",
"engine_version": "1.0.0"
}

277
quick_menu_fix.py Normal file
View File

@ -0,0 +1,277 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
快速菜单栏修复脚本
用于诊断和修复菜单栏显示问题
"""
import sys
import os
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QPushButton
from PyQt5.QtCore import Qt, QTimer
# 设置环境变量避免DPI问题
os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
os.environ["QT_SCALE_FACTOR"] = "1"
class QuickMenuFix(QMainWindow):
def __init__(self):
super().__init__()
self.setupUI()
def setupUI(self):
"""设置UI"""
self.setWindowTitle("菜单栏快速修复工具")
self.setGeometry(300, 300, 900, 700)
# 强制窗口标志
self.setWindowFlags(Qt.Window)
# 设置主窗口样式
self.setStyleSheet("""
QMainWindow {
background-color: #1E1E1E;
color: #FFFFFF;
}
QPushButton {
background-color: #0078D4;
color: white;
border: none;
padding: 10px 20px;
margin: 5px;
border-radius: 5px;
font-size: 12px;
}
QPushButton:hover {
background-color: #106EBE;
}
QPushButton:pressed {
background-color: #005A9E;
}
""")
# 创建中央部件
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
# 标题
title = QLabel("🔧 菜单栏修复工具")
title.setStyleSheet("font-size: 24px; font-weight: bold; color: #0078D4; margin: 20px;")
title.setAlignment(Qt.AlignCenter)
layout.addWidget(title)
# 状态显示
self.status_label = QLabel("准备就绪...")
self.status_label.setStyleSheet("font-size: 14px; color: white; margin: 10px; padding: 10px; background-color: #2D2D30; border-radius: 5px;")
self.status_label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.status_label)
# 按钮区域
button_layout = QVBoxLayout()
# 测试按钮
test_btn = QPushButton("🔍 测试菜单栏显示")
test_btn.clicked.connect(self.testMenuBar)
button_layout.addWidget(test_btn)
# 修复按钮
fix_btn = QPushButton("🛠️ 强制修复菜单栏")
fix_btn.clicked.connect(self.forceFixMenuBar)
button_layout.addWidget(fix_btn)
# 重置按钮
reset_btn = QPushButton("🔄 重置菜单栏样式")
reset_btn.clicked.connect(self.resetMenuBarStyle)
button_layout.addWidget(reset_btn)
# 信息按钮
info_btn = QPushButton("📊 显示系统信息")
info_btn.clicked.connect(self.showSystemInfo)
button_layout.addWidget(info_btn)
layout.addLayout(button_layout)
# 创建初始菜单栏
self.createInitialMenuBar()
def createInitialMenuBar(self):
"""创建初始菜单栏"""
menubar = self.menuBar()
menubar.setNativeMenuBar(False)
# 添加基本菜单
file_menu = menubar.addMenu('文件')
file_menu.addAction('新建')
file_menu.addAction('打开')
edit_menu = menubar.addMenu('编辑')
edit_menu.addAction('复制')
edit_menu.addAction('粘贴')
help_menu = menubar.addMenu('帮助')
help_menu.addAction('关于')
print("✅ 初始菜单栏已创建")
def testMenuBar(self):
"""测试菜单栏显示"""
menubar = self.menuBar()
# 收集信息
info = []
info.append(f"可见性: {menubar.isVisible()}")
info.append(f"启用状态: {menubar.isEnabled()}")
info.append(f"高度: {menubar.height()}px")
info.append(f"宽度: {menubar.width()}px")
info.append(f"位置: {menubar.pos()}")
info.append(f"菜单数量: {len(menubar.actions())}")
info.append(f"原生菜单栏: {menubar.isNativeMenuBar()}")
# 显示结果
status_text = "📊 菜单栏状态:\n" + "\n".join(info)
self.status_label.setText(status_text)
# 控制台输出
print("\n🔍 菜单栏测试结果:")
for item in info:
print(f" - {item}")
# 判断是否正常
if menubar.isVisible() and menubar.height() > 0:
self.status_label.setStyleSheet("font-size: 14px; color: white; margin: 10px; padding: 10px; background-color: #0F7B0F; border-radius: 5px;")
print("✅ 菜单栏显示正常")
else:
self.status_label.setStyleSheet("font-size: 14px; color: white; margin: 10px; padding: 10px; background-color: #A80000; border-radius: 5px;")
print("❌ 菜单栏显示异常")
def forceFixMenuBar(self):
"""强制修复菜单栏"""
menubar = self.menuBar()
print("🛠️ 开始强制修复菜单栏...")
# 重置基本属性
menubar.setNativeMenuBar(False)
menubar.setVisible(True)
menubar.setEnabled(True)
# 设置尺寸
menubar.setMinimumHeight(50)
menubar.setMaximumHeight(50)
# 应用强制样式
menubar.setStyleSheet("""
QMenuBar {
background-color: #FF4444 !important;
color: #FFFFFF !important;
border: 4px solid #00FF00 !important;
min-height: 50px !important;
max-height: 50px !important;
font-size: 18px !important;
font-weight: bold !important;
padding: 8px !important;
}
QMenuBar::item {
background-color: #FFFF00 !important;
color: #000000 !important;
padding: 12px 20px !important;
margin: 4px !important;
font-size: 18px !important;
font-weight: bold !important;
border: 2px solid #FF0000 !important;
border-radius: 3px !important;
}
QMenuBar::item:selected {
background-color: #0066FF !important;
color: #FFFFFF !important;
}
""")
# 强制显示和刷新
menubar.show()
menubar.raise_()
menubar.update()
menubar.repaint()
self.update()
self.repaint()
self.status_label.setText("🛠️ 强制修复已应用!\n如果看到红色菜单栏说明修复成功")
self.status_label.setStyleSheet("font-size: 14px; color: white; margin: 10px; padding: 10px; background-color: #FF6600; border-radius: 5px;")
print("🛠️ 强制修复完成")
# 延迟测试结果
QTimer.singleShot(1000, self.testMenuBar)
def resetMenuBarStyle(self):
"""重置菜单栏样式"""
menubar = self.menuBar()
# 清除样式
menubar.setStyleSheet("")
# 重新设置基本样式
menubar.setStyleSheet("""
QMenuBar {
background-color: #2D2D30;
color: #FFFFFF;
border-bottom: 1px solid #3E3E42;
min-height: 30px;
font-size: 14px;
}
QMenuBar::item {
background-color: transparent;
color: #FFFFFF;
padding: 8px 12px;
margin: 0px 2px;
}
QMenuBar::item:selected {
background-color: #0078D4;
}
""")
menubar.update()
self.status_label.setText("🔄 菜单栏样式已重置为正常样式")
self.status_label.setStyleSheet("font-size: 14px; color: white; margin: 10px; padding: 10px; background-color: #2D2D30; border-radius: 5px;")
print("🔄 菜单栏样式已重置")
def showSystemInfo(self):
"""显示系统信息"""
import platform
from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR
info = []
info.append(f"操作系统: {platform.system()} {platform.release()}")
info.append(f"Python版本: {sys.version.split()[0]}")
info.append(f"PyQt5版本: {PYQT_VERSION_STR}")
info.append(f"Qt版本: {QT_VERSION_STR}")
info.append(f"屏幕分辨率: {QApplication.desktop().screenGeometry().width()}x{QApplication.desktop().screenGeometry().height()}")
status_text = "📊 系统信息:\n" + "\n".join(info)
self.status_label.setText(status_text)
self.status_label.setStyleSheet("font-size: 12px; color: white; margin: 10px; padding: 10px; background-color: #0078D4; border-radius: 5px;")
print("\n📊 系统信息:")
for item in info:
print(f" - {item}")
def main():
"""主函数"""
app = QApplication(sys.argv)
# 设置应用样式
app.setStyle('Fusion')
print("🚀 启动菜单栏修复工具")
print("📋 这个工具可以帮助诊断和修复菜单栏显示问题")
print("🎯 使用明显的颜色来测试菜单栏是否正常显示")
window = QuickMenuFix()
window.show()
return app.exec_()
if __name__ == "__main__":
sys.exit(main())

28
scripts/a.py Normal file
View File

@ -0,0 +1,28 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
a - 自定义脚本
"""
from core.script_system import ScriptBase
class A(ScriptBase):
"""自定义脚本类"""
def __init__(self):
super().__init__()
# 在这里初始化您的变量
def start(self):
"""脚本开始时调用"""
self.log("脚本开始运行!")
def update(self, dt):
"""每帧更新"""
# 在这里编写更新逻辑
pass
def on_destroy(self):
"""脚本销毁时调用"""
self.log("脚本被销毁")

View File

@ -69,6 +69,9 @@ class IconManager:
'success_icon': 'success_icon.png',
'warning_icon': 'warning_icon.png',
'fail_icon': 'delete_fail_icon.png',
# 属性面板图标
'property_select_image': 'property_select_image.png',
}
# 初始化默认图标

View File

@ -1504,8 +1504,8 @@ class MainWindow(QMainWindow):
padding: 8px 10px;
border-bottom: none;
text-align: left;
font-family: 'Microsoft YaHei', 'Inter', sans-serif;
font-size: 14px;
font-family: 'Inter', 'Microsoft YaHei', sans-serif;
font-size: 12px;
font-weight: 500;
}
QDockWidget::close-button {
@ -1540,6 +1540,7 @@ class MainWindow(QMainWindow):
background-color: #19191b;
color: #ebebeb;
border: none;
padding: 0px 0px 0px 8px;
alternate-background-color: #19191b;
font-family: 'Microsoft YaHei', 'Inter', sans-serif;
font-size: 10px;
@ -1844,16 +1845,16 @@ class MainWindow(QMainWindow):
/* 设置内边距为标题和内容留出空间左右内边距与主标题对齐 */
padding-top: 20px; /* 为标题留出足够空间 */
padding-left: 8px; /* 左内边距与主标题分隔线对齐 */
padding-right: 8px; /* 右内边距与主标题分隔线对齐 */
padding-left: 0px; /* Align subtitle with dock title baseline */
padding-right: 0px; /* 右内边距与主标题分隔线对齐 */
/* 减少下边距使相邻组更紧凑 */
background-color: transparent;
margin-bottom: 6px;
/* 使用边框创建样式线与主标题分隔线保持相同的8px左右间距 */
border-top: 1px solid rgba(77, 116, 189, 0.4);
margin-left: 8px;
margin-left: 0px;
margin-right: 8px;
}
@ -1863,7 +1864,7 @@ class MainWindow(QMainWindow):
subcontrol-position: top left;
/* 标题样式左边距为0因为已经通过padding-left处理了对齐 */
padding: 5px 3px 8px 0px; /* 左边距设为0与内容对齐 */
padding: 8px 3px 8px 0px; /* 左边距设为0与内容对齐 */
margin-top: 0px; /* 标题紧贴内边距顶部 */
/* 移除标题上的边框 */
@ -1875,6 +1876,13 @@ class MainWindow(QMainWindow):
font-size: 12px;
font-weight: 500;
}
QGroupBox[groupRole="first"] {
padding-top: 16px;
margin-top: 0px;
}
QGroupBox[groupRole="first"]::title {
padding: 6px 3px 8px 0px;
}
""")
# 创建属性面板的主容器和布局
@ -1883,7 +1891,9 @@ class MainWindow(QMainWindow):
try:
self.propertyLayout = QVBoxLayout(self.propertyContainer)
self.propertyLayout.setContentsMargins(0, 0, 0, 0)
# Keep subtitles aligned with the dock title left padding
self.propertyLayout.setContentsMargins(10, 0, 10, 12)
self.propertyLayout.setSpacing(12)
print(f"✓ 属性布局创建完成: {self.propertyLayout}")
# 添加初始提示信息
@ -2032,7 +2042,7 @@ class MainWindow(QMainWindow):
subcontrol-position: top left;
/* 标题样式左边距为0因为已经通过padding-left处理了对齐 */
padding: 5px 3px 8px 0px; /* 左边距设为0与内容对齐 */
padding: 8px 3px 8px 0px; /* 左边距设为0与内容对齐 */
margin-top: 0px; /* 标题紧贴内边距顶部 */
/* 移除标题上的边框 */
@ -2044,6 +2054,13 @@ class MainWindow(QMainWindow):
font-size: 12px;
font-weight: 500;
}
QGroupBox[groupRole="first"] {
padding-top: 16px;
margin-top: 0px;
}
QGroupBox[groupRole="first"]::title {
padding: 6px 3px 8px 0px;
}
""")
# 创建脚本面板的主容器和布局(与属性面板相同结构)
@ -2056,6 +2073,9 @@ class MainWindow(QMainWindow):
""")
self.scriptContainer.setObjectName("ScriptContainer")
self.scriptLayout = QVBoxLayout(self.scriptContainer)
# Match the dock title horizontal padding for consistent alignment
self.scriptLayout.setContentsMargins(10, 0, 10, 12)
self.scriptLayout.setSpacing(12)
# 创建滚动区域并设置属性
self.scriptScrollArea = QScrollArea()
@ -2215,6 +2235,14 @@ class MainWindow(QMainWindow):
font-size: 12px;
font-weight: 500;
}
QGroupBox[groupRole="first"] {
border-top: none;
margin-top: 0px;
padding-top: 8px;
}
QGroupBox[groupRole="first"]::title {
padding: 8px 5px 8px 0px;
}
""")
# 创建包装容器,添加标题下方的分隔线
@ -2238,7 +2266,14 @@ class MainWindow(QMainWindow):
}
""")
bottomDockLayout.addWidget(bottomSeparator)
bottomDockLayout.addWidget(self.fileView)
# Wrap the resource view to add consistent left padding
resourceContentWrapper = QWidget()
resourceContentLayout = QVBoxLayout(resourceContentWrapper)
resourceContentLayout.setContentsMargins(8, 0, 0, 0)
resourceContentLayout.setSpacing(0)
resourceContentLayout.addWidget(self.fileView)
bottomDockLayout.addWidget(resourceContentWrapper)
self.bottomDock.setWidget(bottomDockContainer)
self.addDockWidget(Qt.BottomDockWidgetArea, self.bottomDock)
@ -2514,6 +2549,8 @@ class MainWindow(QMainWindow):
"""创建脚本管理面板"""
# 脚本状态组
statusGroup = QGroupBox("脚本系统状态")
statusGroup.setProperty("groupRole", "first")
statusLayout = QVBoxLayout()
# 脚本系统状态行

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@ from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout,
QTreeView, QTreeWidget, QTreeWidgetItem, QWidget,
QFileDialog, QMessageBox, QAbstractItemView, QMenu, QDockWidget, QButtonGroup, QToolButton, QFrame, QSizePolicy)
from PyQt5.QtCore import Qt, QUrl, QMimeData, QPoint, QSize
from PyQt5.QtGui import QDrag, QPainter, QPixmap, QPen, QBrush
from PyQt5.QtGui import QDrag, QPainter, QPixmap, QPen, QBrush, QFont
from PyQt5.sip import wrapinstance
from direct.showbase.ShowBaseGlobal import aspect2d
from panda3d.core import ModelRoot, NodePath, CollisionNode
@ -592,6 +592,13 @@ class CustomFileView(QTreeView):
if parent is None:
parent = wrapinstance(0, QWidget)
super().__init__(parent)
base_font = self.font()
base_font.setFamily("Inter")
base_font.setPointSize(10)
base_font.setWeight(QFont.Normal)
self.setFont(base_font)
if self.model():
self.model().rowsInserted.connect(self._handle_rows_inserted)
self.world = world
self.setupUI()
self.setupDragDrop()
@ -2136,7 +2143,7 @@ class UniversalMessageDialog(QDialog):
INFO = "info"
def __init__(self, parent, title, message, message_type=INFO, show_cancel=True,
confirm_text="确认", cancel_text="取消", icon_size=QSize(48, 48)):
confirm_text="确认", cancel_text="取消", icon_size=QSize(20, 20)):
"""
初始化通用消息对话框
@ -2353,14 +2360,20 @@ class UniversalMessageDialog(QDialog):
message_area = QHBoxLayout()
message_area.setContentsMargins(0, 0, 0, 0)
message_area.setSpacing(15)
message_area.setSpacing(10)
# 用一个垂直布局包裹icon_label确保顶部对齐
icon_vbox = QVBoxLayout()
icon_vbox.setContentsMargins(0, 0, 0, 0)
icon_vbox.setSpacing(0)
icon_label = QLabel()
if self._message_icon and not self._message_icon.isNull():
icon_label.setPixmap(self._message_icon.pixmap(self.icon_size))
icon_label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
icon_label.setFixedSize(self.icon_size)
message_area.addWidget(icon_label)
icon_vbox.addWidget(icon_label, alignment=Qt.AlignTop)
icon_vbox.addStretch()
message_area.addLayout(icon_vbox)
self.message_label = QLabel(message)
self.message_label.setObjectName('messageLabel')
@ -3517,15 +3530,51 @@ class CustomTreeWidget(QTreeWidget):
sceneRoot = QTreeWidgetItem(self, ['场景'])
sceneRoot.setData(0, Qt.UserRole, self.world.render)
sceneRoot.setData(0, Qt.UserRole + 1, "SCENE_ROOT")
self._apply_font_to_item(sceneRoot)
# 添加相机节点
cameraItem = QTreeWidgetItem(sceneRoot, ['相机'])
cameraItem.setData(0, Qt.UserRole, self.world.cam)
cameraItem.setData(0, Qt.UserRole + 1, "CAMERA_NODE")
self._apply_font_to_item(cameraItem)
# 添加地板节点
if hasattr(self.world, 'ground') and self.world.ground:
groundItem = QTreeWidgetItem(sceneRoot, ['地板'])
groundItem.setData(0, Qt.UserRole, self.world.ground)
groundItem.setData(0,Qt.UserRole + 1, "SCENE_NODE")
self._apply_font_to_item(groundItem)
def _apply_font_to_item(self, item):
"""根据节点层级设置字体大小"""
if not item:
return
font = QFont(self.font())
marker = item.data(0, Qt.UserRole + 1)
if item.parent() is None and (marker == "SCENE_ROOT" or item.text(0) == '场景'):
font.setPointSize(12)
font.setWeight(QFont.Medium)
else:
font.setPointSize(10)
font.setWeight(QFont.Normal)
item.setFont(0, font)
def _apply_font_recursively(self, item):
"""递归应用字体样式"""
if not item:
return
self._apply_font_to_item(item)
for index in range(item.childCount()):
self._apply_font_recursively(item.child(index))
def _handle_rows_inserted(self, parent_index, first, last):
"""在插入新节点时自动调整字体"""
model = self.model()
if not model:
return
for row in range(first, last + 1):
index = model.index(row, 0, parent_index)
item = self.itemFromIndex(index)
if item:
self._apply_font_recursively(item)
def _cleanup_panda_node_resources(self, panda_node):
"""一个集中的辅助函数用于清理与Panda3D节点相关的所有资源。"""