EG/ui/main_window.py
2025-07-02 09:49:59 +08:00

258 lines
10 KiB
Python

"""
主窗口设置模块
负责主窗口的界面构建和事件绑定:
- 菜单栏、工具栏创建
- 停靠窗口设置
- 事件连接和信号处理
"""
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QMenu, QAction,
QDockWidget, QTreeWidget, QListWidget, QWidget, QVBoxLayout, QTreeWidgetItem,
QLabel, QLineEdit, QFormLayout, QDoubleSpinBox, QScrollArea,
QFileSystemModel, QButtonGroup, QToolButton)
from PyQt5.QtCore import Qt, QDir
from ui.widgets import CustomPanda3DWidget, CustomFileView, CustomTreeWidget
class MainWindow(QMainWindow):
"""主窗口类"""
def __init__(self, world):
super().__init__()
self.world = world
self.setupWindow()
self.setupMenus()
self.setupDockWindows()
self.setupToolbar()
self.connectEvents()
def setupWindow(self):
"""设置窗口基本属性"""
self.setGeometry(50, 50, 1920, 1080)
self.setWindowTitle("引擎编辑器")
# 使用自定义的 Panda3D 部件作为中央部件
self.pandaWidget = CustomPanda3DWidget(self.world)
self.setCentralWidget(self.pandaWidget)
def setupMenus(self):
"""创建菜单栏"""
menubar = self.menuBar()
# 文件菜单
self.fileMenu = menubar.addMenu('文件')
self.newAction = self.fileMenu.addAction('新建')
self.openAction = self.fileMenu.addAction('打开')
self.saveAction = self.fileMenu.addAction('保存')
self.buildAction = self.fileMenu.addAction('打包')
self.fileMenu.addSeparator()
self.exitAction = self.fileMenu.addAction('退出')
# 编辑菜单
self.editMenu = menubar.addMenu('编辑')
self.undoAction = self.editMenu.addAction('撤销')
self.redoAction = self.editMenu.addAction('重做')
self.editMenu.addSeparator()
self.cutAction = self.editMenu.addAction('剪切')
self.copyAction = self.editMenu.addAction('复制')
self.pasteAction = self.editMenu.addAction('粘贴')
# 视图菜单
self.viewMenu = menubar.addMenu('视图')
self.viewPerspectiveAction = self.viewMenu.addAction('透视图')
self.viewTopAction = self.viewMenu.addAction('俯视图')
self.viewFrontAction = self.viewMenu.addAction('前视图')
self.viewMenu.addSeparator()
self.viewGridAction = self.viewMenu.addAction('显示网格')
# 工具菜单
self.toolsMenu = menubar.addMenu('工具')
self.selectAction = self.toolsMenu.addAction('选择工具')
self.moveAction = self.toolsMenu.addAction('移动工具')
self.rotateAction = self.toolsMenu.addAction('旋转工具')
self.scaleAction = self.toolsMenu.addAction('缩放工具')
# GUI菜单
self.guiMenu = menubar.addMenu('GUI')
self.guiEditModeAction = self.guiMenu.addAction('进入GUI编辑模式')
self.guiMenu.addSeparator()
self.createButtonAction = self.guiMenu.addAction('创建按钮')
self.createLabelAction = self.guiMenu.addAction('创建标签')
self.createEntryAction = self.guiMenu.addAction('创建输入框')
self.guiMenu.addSeparator()
self.create3DTextAction = self.guiMenu.addAction('创建3D文本')
self.createVirtualScreenAction = self.guiMenu.addAction('创建虚拟屏幕')
# 帮助菜单
self.helpMenu = menubar.addMenu('帮助')
self.aboutAction = self.helpMenu.addAction('关于')
def setupDockWindows(self):
"""创建停靠窗口"""
# 创建左侧停靠窗口(层级窗口)
self.leftDock = QDockWidget("层级", self)
self.leftDock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
self.treeWidget = CustomTreeWidget(self.world)
self.treeWidget.setHeaderLabel("场景")
self.world.setTreeWidget(self.treeWidget) # 设置树形控件引用
self.leftDock.setWidget(self.treeWidget)
self.leftDock.setMinimumWidth(300)
self.addDockWidget(Qt.LeftDockWidgetArea, self.leftDock)
# 创建右侧停靠窗口(属性窗口)
self.rightDock = QDockWidget("属性", self)
self.rightDock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
# 创建属性面板的主容器和布局
self.propertyContainer = QWidget()
self.propertyContainer.setObjectName("PropertyContainer")
self.propertyLayout = QFormLayout(self.propertyContainer)
# 添加初始提示信息
tipLabel = QLabel("")
tipLabel.setStyleSheet("color: gray;") # 使用灰色字体
self.propertyLayout.addRow(tipLabel)
# 创建滚动区域并设置属性
self.scrollArea = QScrollArea()
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setWidget(self.propertyContainer)
# 设置滚动区域为停靠窗口的主部件
self.rightDock.setWidget(self.scrollArea)
self.rightDock.setMinimumWidth(300)
self.addDockWidget(Qt.RightDockWidgetArea, self.rightDock)
# 设置属性面板到世界对象
self.world.setPropertyLayout(self.propertyLayout)
# 创建底部停靠窗口(资源窗口)
self.bottomDock = QDockWidget("资源", self)
self.bottomDock.setAllowedAreas(Qt.BottomDockWidgetArea)
# 创建文件系统模型
self.fileModel = QFileSystemModel()
self.fileModel.setRootPath(QDir.homePath()) # 设置为用户主目录
# 创建树形视图显示文件系统
self.fileView = CustomFileView(self.world)
self.fileView.setModel(self.fileModel)
self.fileView.setRootIndex(self.fileModel.index(QDir.homePath())) # 设置为用户主目录索引
# 设置列宽
self.fileView.setColumnWidth(0, 250) # 名称列
self.fileView.setColumnWidth(1, 100) # 大小列
self.fileView.setColumnWidth(2, 100) # 类型列
self.fileView.setColumnWidth(3, 150) # 修改日期列
# 设置视图属性
self.fileView.setMinimumHeight(200) # 设置最小高度
self.bottomDock.setWidget(self.fileView)
self.addDockWidget(Qt.BottomDockWidgetArea, self.bottomDock)
def setupToolbar(self):
"""创建工具栏"""
self.toolbar = self.addToolBar('工具栏')
# 创建工具按钮组
self.toolGroup = QButtonGroup()
# 选择工具
self.selectTool = QToolButton()
self.selectTool.setText("选择")
self.selectTool.setCheckable(True)
self.toolGroup.addButton(self.selectTool)
self.toolbar.addWidget(self.selectTool)
# 旋转工具
self.rotateTool = QToolButton()
self.rotateTool.setText("旋转")
self.rotateTool.setCheckable(True)
self.toolGroup.addButton(self.rotateTool)
self.toolbar.addWidget(self.rotateTool)
# 缩放工具
self.scaleTool = QToolButton()
self.scaleTool.setText("缩放")
self.scaleTool.setCheckable(True)
self.toolGroup.addButton(self.scaleTool)
self.toolbar.addWidget(self.scaleTool)
# 添加分隔符
self.toolbar.addSeparator()
# GUI创建工具
self.createButtonTool = QToolButton()
self.createButtonTool.setText("创建按钮")
self.toolbar.addWidget(self.createButtonTool)
self.createLabelTool = QToolButton()
self.createLabelTool.setText("创建标签")
self.toolbar.addWidget(self.createLabelTool)
self.create3DTextTool = QToolButton()
self.create3DTextTool.setText("3D文本")
self.toolbar.addWidget(self.create3DTextTool)
# 默认选择"选择"工具
self.selectTool.setChecked(True)
self.world.setCurrentTool("选择")
def connectEvents(self):
"""连接事件信号"""
# 导入项目管理功能函数
from main import createNewProject, saveProject, openProject, buildPackage
# 连接文件菜单事件
self.newAction.triggered.connect(lambda: createNewProject(self))
self.openAction.triggered.connect(lambda: openProject(self))
self.saveAction.triggered.connect(lambda: saveProject(self))
self.buildAction.triggered.connect(lambda: buildPackage(self))
self.exitAction.triggered.connect(QApplication.instance().quit)
# 连接GUI编辑模式事件
self.guiEditModeAction.triggered.connect(lambda: self.world.toggleGUIEditMode())
# 连接GUI创建按钮事件
self.createButtonAction.triggered.connect(lambda: self.world.createGUIButton())
self.createLabelAction.triggered.connect(lambda: self.world.createGUILabel())
self.createEntryAction.triggered.connect(lambda: self.world.createGUIEntry())
self.create3DTextAction.triggered.connect(lambda: self.world.createGUI3DText())
self.createVirtualScreenAction.triggered.connect(lambda: self.world.createGUIVirtualScreen())
# 连接工具栏GUI创建按钮事件
self.createButtonTool.clicked.connect(lambda: self.world.createGUIButton())
self.createLabelTool.clicked.connect(lambda: self.world.createGUILabel())
self.create3DTextTool.clicked.connect(lambda: self.world.createGUI3DText())
# 连接树节点点击信号
self.treeWidget.itemClicked.connect(self.world.onTreeItemClicked)
print("已连接点击信号")
# 连接工具切换信号
self.toolGroup.buttonClicked.connect(self.onToolChanged)
def onToolChanged(self, button):
"""工具切换事件处理"""
if button.isChecked():
tool_name = button.text()
self.world.setCurrentTool(tool_name)
print(f"工具栏: 选择了 {tool_name} 工具")
else:
self.world.setCurrentTool(None)
print("工具栏: 取消选择工具")
def setup_main_window(world):
"""设置主窗口的便利函数"""
app = QApplication.instance()
if app is None:
app = QApplication(sys.argv)
main_window = MainWindow(world)
main_window.show()
return app, main_window