#include "mainwindow.h" #include "database_manager/databasemodule.h" #include "daemon/daemon_client.h" #include "daemon/daemon_connection_dialog.h" #include "daemon/daemon_message_flow_widget.h" #include "api/SoftBusAPI.h" #include "settings/settings_dialog.h" #include "toolbar/toolbar.h" #include "view_serial/serialmodule.h" #include "utils/logging.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { createUI(); } void MainWindow::createUI() { // 创建菜单栏 createMenuBar(); // 创建主布局 QWidget *centralWidget = new QWidget(this); QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget); // 界面设置 setWindowTitle("软件总线"); setWindowIcon(QIcon(":/qrc/icons/ads_icon.svg")); setUnifiedTitleAndToolBarOnMac(true); setDockNestingEnabled(true); setAnimated(true); setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); setDockOptions(QMainWindow::AllowTabbedDocks | QMainWindow::AnimatedDocks | QMainWindow::VerticalTabs); setStatusBar(new QStatusBar(this)); setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); setMinimumSize(800, 600); setMaximumSize(1600, 1200); // 创建页面堆栈 m_pageStack = new QStackedWidget(this); mainLayout->addWidget(m_pageStack); centralWidget->setLayout(mainLayout); setCentralWidget(centralWidget); // 先设置守护进程状态(必须在创建模块之前,因为模块可能会初始化 API) setupDaemonStatus(); // 创建工具栏和页面(在守护进程设置之后) createHomeToolbar(); createSerialToolbar(); createDatabaseToolbar(); createSettingsToolbar(); createHelpToolbar(); // 默认显示主界面 switchToPage(1); // 设置快捷键 setupShortcuts(); // 链接信号槽 connectSignals(); // 创建状态栏 this->statusBar()->showMessage("就绪"); } void MainWindow::createMenuBar() { // 创建菜单栏 QMenuBar *menuBar = new QMenuBar(this); setMenuBar(menuBar); // 视图菜单 QMenu *viewMenu = menuBar->addMenu("视图"); QAction *homeAction = viewMenu->addAction(QIcon(":/qrc/icons/home.png"), "主界面"); QAction *serialAction = viewMenu->addAction(QIcon(":/qrc/icons/serial.png"), "串口"); QAction *databaseAction = viewMenu->addAction(QIcon(":/qrc/icons/grid_on.svg"), "数据库"); QAction *settingsAction = viewMenu->addAction(QIcon(":/qrc/icons/settings.png"), "设置"); QAction *helpAction = viewMenu->addAction(QIcon(":/qrc/icons/help.png"), "帮助"); // 连接视图菜单的切换功能 connect(homeAction, &QAction::triggered, this, [this]() { switchToPage(0); }); connect(serialAction, &QAction::triggered, this, [this]() { switchToPage(1); }); connect(databaseAction, &QAction::triggered, this, [this]() { switchToPage(2); }); connect(settingsAction, &QAction::triggered, this, [this]() { switchToPage(3); }); connect(helpAction, &QAction::triggered, this, [this]() { switchToPage(4); }); // 文件菜单 QMenu *fileMenu = menuBar->addMenu("文件"); QAction *newAction = fileMenu->addAction(QIcon(":/qrc/icons/new.png"), "新建"); QAction *openAction = fileMenu->addAction(QIcon(":/qrc/icons/open.png"), "打开"); QAction *saveAction = fileMenu->addAction(QIcon(":/qrc/icons/save.png"), "保存"); fileMenu->addSeparator(); QAction *exitAction = fileMenu->addAction(QIcon(":/qrc/icons/exit.png"), "退出"); // 编辑菜单 QMenu *editMenu = menuBar->addMenu("编辑"); QAction *undoAction = editMenu->addAction(QIcon(":/qrc/icons/undo.png"), "撤销"); QAction *redoAction = editMenu->addAction(QIcon(":/qrc/icons/redo.png"), "重做"); editMenu->addSeparator(); QAction *cutAction = editMenu->addAction(QIcon(":/qrc/icons/cut.png"), "剪切"); QAction *copyAction = editMenu->addAction(QIcon(":/qrc/icons/copy.png"), "复制"); QAction *pasteAction = editMenu->addAction(QIcon(":/qrc/icons/paste.png"), "粘贴"); // 帮助菜单 QMenu *helpMenu = menuBar->addMenu("帮助"); QAction *helpDocAction = helpMenu->addAction(QIcon(":/qrc/icons/help.png"), "帮助文档"); QAction *aboutAction = helpMenu->addAction(QIcon(":/qrc/icons/about.png"), "关于"); QAction *updateAction = helpMenu->addAction(QIcon(":/qrc/icons/update.png"), "检查更新"); connect(aboutAction, &QAction::triggered, this, &MainWindow::showAbout); // 连接退出菜单项,真正退出应用 connect(exitAction, &QAction::triggered, qApp, &QApplication::quit); } void MainWindow::createHomeToolbar() { // 创建主界面工具栏 Toolbar *homeToolbar = new Toolbar("主工具栏", this); addToolBar(Qt::TopToolBarArea, homeToolbar); homeToolbar->hide(); // 添加按钮 homeToolbar->addAction(QIcon(":/qrc/icons/new.png"), "新建"); homeToolbar->addAction(QIcon(":/qrc/icons/open.png"), "打开"); homeToolbar->addAction(QIcon(":/qrc/icons/save.png"), "保存"); homeToolbar->addAction(QIcon(":/qrc/icons/print.png"), "打印"); // 创建主界面页面 QLabel *homePage = new QLabel("

主界面

", this); homePage->setAlignment(Qt::AlignCenter); // 添加到堆栈 m_toolbars.append(homeToolbar); m_pageStack->addWidget(homePage); } void MainWindow::createSerialToolbar() { if (!m_serialModule) { m_serialModule = new SerialModule(this, this); } if (Toolbar *serialToolbar = m_serialModule->toolbar()) { addToolBar(Qt::TopToolBarArea, serialToolbar); serialToolbar->hide(); m_toolbars.append(serialToolbar); } if (QWidget *serialPage = m_serialModule->pageWidget()) { m_serialPageIndex = m_pageStack->addWidget(serialPage); } } void MainWindow::createDatabaseToolbar() { if (!m_databaseModule) { m_databaseModule = new DatabaseModule(this, this); } if (Toolbar *databaseToolbar = m_databaseModule->toolbar()) { addToolBar(Qt::TopToolBarArea, databaseToolbar); databaseToolbar->hide(); m_toolbars.append(databaseToolbar); } if (QWidget *databasePage = m_databaseModule->pageWidget()) { m_databasePageIndex = m_pageStack->addWidget(databasePage); } } void MainWindow::createSettingsToolbar() { // 创建设置界面工具栏 Toolbar *settingsToolbar = new Toolbar("设置工具栏", this); addToolBar(Qt::TopToolBarArea, settingsToolbar); settingsToolbar->hide(); // 添加按钮 QAction *preferencesAction = settingsToolbar->addAction(QIcon(":/qrc/icons/preferences.png"), "首选项"); connect(preferencesAction, &QAction::triggered, this, &MainWindow::showSettingsDialog); settingsToolbar->addAction(QIcon(":/qrc/icons/theme.png"), "主题"); settingsToolbar->addAction(QIcon(":/qrc/icons/keyboard.png"), "快捷键"); settingsToolbar->addAction(QIcon(":/qrc/icons/plugins.png"), "插件"); // 创建设置界面页面 QLabel *settingsPage = new QLabel("

设置界面

点击工具栏中的\"首选项\"按钮打开设置对话框

", this); settingsPage->setAlignment(Qt::AlignCenter); // 添加到堆栈 m_toolbars.append(settingsToolbar); m_pageStack->addWidget(settingsPage); } void MainWindow::createHelpToolbar() { // 创建帮助界面工具栏 Toolbar *helpToolbar = new Toolbar("帮助工具栏", this); addToolBar(Qt::TopToolBarArea, helpToolbar); helpToolbar->hide(); // 添加按钮 helpToolbar->addAction(QIcon(":/qrc/icons/help.png"), "帮助文档"); helpToolbar->addAction(QIcon(":/qrc/icons/about.png"), "关于"); helpToolbar->addAction(QIcon(":/qrc/icons/update.png"), "检查更新"); // 创建帮助界面页面 QLabel *helpPage = new QLabel("

帮助界面

", this); helpPage->setAlignment(Qt::AlignCenter); // 添加到堆栈 m_toolbars.append(helpToolbar); m_pageStack->addWidget(helpPage); } /* function: 返回指定索引的页面 @author: flower @date: 2025-10-23 @param index 页面索引 @return 无 */ void MainWindow::switchToPage(int index) { // 隐藏所有工具栏 for (Toolbar *toolbar : m_toolbars) { toolbar->hide(); } // 显示当前工具栏 if (index >= 0 && index < m_toolbars.size()) { m_toolbars[index]->show(); m_pageStack->setCurrentIndex(index); } } /* function: 设置快捷键 @author: flower @date: 2025-10-23 @param @return 无 */ void MainWindow::setupShortcuts() { // 创建快捷键 QShortcut *homeShortcut = new QShortcut(QKeySequence("Ctrl+1"), this); QShortcut *serialShortcut = new QShortcut(QKeySequence("Ctrl+2"), this); QShortcut *databaseShortcut = new QShortcut(QKeySequence("Ctrl+3"), this); QShortcut *settingsShortcut = new QShortcut(QKeySequence("Ctrl+4"), this); QShortcut *helpShortcut = new QShortcut(QKeySequence("Ctrl+5"), this); // 连接快捷键信号 connect(homeShortcut, &QShortcut::activated, this, [this]() { switchToPage(0); }); connect(serialShortcut, &QShortcut::activated, this, [this]() { switchToPage(1); }); connect(databaseShortcut, &QShortcut::activated, this, [this]() { switchToPage(2); }); connect(settingsShortcut, &QShortcut::activated, this, [this]() { switchToPage(3); }); connect(helpShortcut, &QShortcut::activated, this, [this]() { switchToPage(4); }); } /* function: 链接信号槽 @author: flower @date: 2021-10-23 @param @return 无 */ void MainWindow::connectSignals() { // 连接信号槽 } void MainWindow::showAbout() { QMessageBox::about(this, "关于", "

基于DoDAF的多源数据融合系统总线

" "

" "

版本: 1.0.0

" "

© flower

"); } void MainWindow::setupDaemonStatus() { // 创建守护进程客户端 m_daemonClient = new DaemonClient(this); // 连接信号 connect(m_daemonClient, &DaemonClient::daemonStatusChanged, this, &MainWindow::onDaemonStatusChanged); connect(m_daemonClient, &DaemonClient::loadInfoUpdated, this, &MainWindow::onLoadInfoUpdated); // 加载设置(在初始化 API 之前) loadSettings(); // 如果设置中启用了守护进程模式,先尝试连接守护进程 // 注意:默认值应该与 loadSettings() 中的默认值一致 // 默认启用守护进程模式,提供更好的资源管理和权限控制 QSettings settings; bool useDaemonMode = settings.value("daemon/useDaemonMode", true).toBool(); SoftBusAPI* api = SoftBusAPI::instance(); bool connected = false; if (useDaemonMode) { // 先尝试启动守护进程(如果未运行) LOG_INFO() << "守护进程模式已启用,正在启动守护进程客户端服务..."; bool daemonStarted = m_daemonClient->startDaemon(); if (daemonStarted) { LOG_INFO() << "守护进程客户端服务启动成功,正在连接守护进程服务..."; } else { LOG_WARNING() << "守护进程启动失败,可能已经运行或无法启动"; } // 尝试连接守护进程(connectToDaemon 内部也会尝试启动) connected = m_daemonClient->connectToDaemon(); if (!connected) { LOG_WARNING() << "守护进程连接失败,弹出对话框询问用户"; // 连接失败,弹出对话框询问是否切换到本地模式 DaemonConnectionDialog dialog(this); dialog.setErrorMessage(tr("守护进程服务未运行或无法访问。")); int result = dialog.exec(); if (result == QDialog::Accepted) { if (dialog.switchToLocalMode()) { // 用户选择切换到本地模式 useDaemonMode = false; settings.setValue("daemon/useDaemonMode", false); settings.sync(); LOG_INFO() << "用户选择切换到本地模式"; } else { // 用户选择重试,再次尝试启动和连接 LOG_INFO() << "用户选择重试,正在重新启动守护进程..."; daemonStarted = m_daemonClient->startDaemon(); connected = m_daemonClient->connectToDaemon(); if (!connected) { // 重试仍然失败,自动切换到本地模式 QMessageBox::warning(this, tr("连接失败"), tr("重试启动和连接守护进程仍然失败,已自动切换到本地模式。")); useDaemonMode = false; settings.setValue("daemon/useDaemonMode", false); settings.sync(); LOG_WARNING() << "重试仍然失败,自动切换到本地模式"; } else { // 重试成功 useDaemonMode = true; LOG_INFO() << "重试启动和连接守护进程成功"; } } } else { // 用户取消,默认切换到本地模式 useDaemonMode = false; settings.setValue("daemon/useDaemonMode", false); settings.sync(); LOG_INFO() << "用户取消对话框,切换到本地模式"; } } else { // 连接成功,确保使用守护进程模式 useDaemonMode = true; LOG_INFO() << "守护进程启动并连接成功"; } } else { LOG_INFO() << "设置中未启用守护进程模式,使用本地模式"; } // 根据最终的模式设置初始化 API // 注意:必须先设置模式,再初始化 API,这样 Manager 才能知道使用哪种模式 LOG_INFO() << "设置API模式:" << (useDaemonMode ? "守护进程模式" : "本地模式"); api->setUseDaemonMode(useDaemonMode); // 初始化 API(会根据模式创建相应的 Manager) LOG_INFO() << "正在初始化 SoftBusAPI..."; if (!api->initialize()) { LOG_WARNING() << "Failed to initialize SoftBusAPI"; return; } LOG_INFO() << "SoftBusAPI 初始化成功"; // 如果使用守护进程模式,设置 DaemonClient 到 SoftBusAPI,让硬件操作通过守护进程 if (useDaemonMode) { LOG_INFO() << "设置 DaemonClient 到 SoftBusAPI"; api->setDaemonClient(m_daemonClient); // 守护进程连接成功后,启动设备扫描(由守护进程负责扫描) // 注意:在守护进程模式下,设备扫描由守护进程负责,这里只是通知可以开始查询设备列表 LOG_INFO() << "启动设备扫描(守护进程模式)"; api->startDeviceDiscovery(5000); } else { // 本地模式下,立即启动设备扫描 LOG_INFO() << "启动设备扫描(本地模式)"; api->startDeviceDiscovery(5000); } // 在状态栏添加状态标签 QStatusBar* statusBar = this->statusBar(); if (statusBar) { m_statusLabel = new QLabel("核心服务: 未连接", this); m_loadLabel = new QLabel("负载: --", this); statusBar->addPermanentWidget(m_statusLabel); statusBar->addPermanentWidget(m_loadLabel); // 初始更新 updateDaemonStatus(false, QString()); } // 创建信息流列表停靠窗口(在守护进程客户端创建之后) createMessageFlowDock(); // 设置守护进程客户端到信息流组件 if (m_daemonClient && m_messageFlowWidget) { m_messageFlowWidget->setDaemonClient(m_daemonClient); } } void MainWindow::onDaemonStatusChanged(bool running, const QString& statusJson) { updateDaemonStatus(running, statusJson); // 信息流组件会自动处理状态更新(通过信号连接) } void MainWindow::onLoadInfoUpdated(const QString& loadInfoJson) { updateLoadInfo(loadInfoJson); // 信息流组件会自动处理负载信息更新(通过信号连接) } void MainWindow::updateDaemonStatus(bool running, const QString& statusJson) { if (!m_statusLabel) return; QString statusText; QString style; if (running) { statusText = "核心服务: 运行中"; style = "color: green; font-weight: bold;"; // 获取进程ID if (m_daemonClient) { qint64 pid = m_daemonClient->getPid(); if (pid > 0) { statusText += QString(" (PID: %1)").arg(pid); } } // 解析状态 JSON 获取详细信息 if (!statusJson.isEmpty()) { QJsonDocument doc = QJsonDocument::fromJson(statusJson.toUtf8()); if (doc.isObject()) { QJsonObject obj = doc.object(); int deviceCount = obj["deviceCount"].toInt(0); int onlineCount = obj["onlineDeviceCount"].toInt(0); statusText += QString(" | 设备: %1/%2").arg(onlineCount).arg(deviceCount); } } } else { statusText = "核心服务: 未运行"; style = "color: red; font-weight: bold;"; } m_statusLabel->setText(statusText); m_statusLabel->setStyleSheet(style); } void MainWindow::updateLoadInfo(const QString& loadInfoJson) { if (!m_loadLabel) return; if (loadInfoJson.isEmpty()) { m_loadLabel->setText("负载: --"); return; } QJsonDocument doc = QJsonDocument::fromJson(loadInfoJson.toUtf8()); if (!doc.isObject()) { m_loadLabel->setText("负载: --"); return; } QJsonObject obj = doc.object(); double messageRate = obj["messageRate"].toDouble(0.0); qint64 totalMessages = obj["totalMessages"].toVariant().toLongLong(); QString loadText = QString("消息速率: %1 msg/s | 总计: %2") .arg(messageRate, 0, 'f', 1) .arg(totalMessages); m_loadLabel->setText(loadText); } void MainWindow::createMessageFlowDock() { // 创建信息流列表组件 m_messageFlowWidget = new DaemonMessageFlowWidget(this); // 创建停靠窗口 QDockWidget* dockWidget = new QDockWidget("守护进程信息流", this); dockWidget->setWidget(m_messageFlowWidget); dockWidget->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea); dockWidget->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); // 添加到主窗口 addDockWidget(Qt::BottomDockWidgetArea, dockWidget); // 设置守护进程客户端 if (m_daemonClient) { m_messageFlowWidget->setDaemonClient(m_daemonClient); } // 默认隐藏,可以通过视图菜单显示 dockWidget->hide(); // 添加到视图菜单 QMenuBar* menuBar = this->menuBar(); if (menuBar) { QMenu* viewMenu = nullptr; QList actions = menuBar->actions(); for (QAction* action : actions) { if (action->text() == "视图") { viewMenu = qobject_cast(action->menu()); break; } } if (viewMenu) { QAction* flowAction = viewMenu->addAction("守护进程信息流"); flowAction->setCheckable(true); flowAction->setChecked(false); connect(flowAction, &QAction::toggled, dockWidget, &QDockWidget::setVisible); } } } void MainWindow::loadSettings() { QSettings settings; // 默认启用守护进程模式,提供更好的资源管理和权限控制 bool useDaemonMode = settings.value("daemon/useDaemonMode", true).toBool(); SoftBusAPI* api = SoftBusAPI::instance(); if (api) { api->setUseDaemonMode(useDaemonMode); LOG_DEBUG() << "加载设置 - 守护进程模式:" << (useDaemonMode ? "启用" : "禁用"); } } void MainWindow::showSettingsDialog() { if (!m_settingsDialog) { m_settingsDialog = new SettingsDialog(this); // 设置守护进程客户端,让设置对话框能检查守护进程状态 m_settingsDialog->setDaemonClient(m_daemonClient); } // 加载当前设置 m_settingsDialog->loadSettings(); // 显示对话框 if (m_settingsDialog->exec() == QDialog::Accepted) { // 用户点击了"确定",应用设置 bool useDaemonMode = m_settingsDialog->useDaemonMode(); SoftBusAPI* api = SoftBusAPI::instance(); if (api) { api->setUseDaemonMode(useDaemonMode); LOG_DEBUG() << "设置已更新 - 守护进程模式:" << (useDaemonMode ? "启用" : "禁用"); } } } void MainWindow::closeEvent(QCloseEvent *event) { // 关闭窗口时只是隐藏窗口,不退出应用 // 这样总线核心可以继续在后台运行 hide(); event->ignore(); // 忽略关闭事件,不真正关闭窗口 // 更新状态栏提示 if (statusBar()) { statusBar()->showMessage("窗口已隐藏,总线核心继续运行中...", 3000); } }