#include "LaunchPage.h" #include "ui_LaunchPage.h" #include #include #include #include #if CONFIG_EN_SUB_THREAD #include SubThread LP_ST; #endif // WindowWorker类实现 void WindowWorker::initialize() { // 执行耗时的数据初始化工作 QVariant initData; // 根据不同页面索引准备不同的数据 switch(m_pageIndex) { case 1:{emit logMessage(QString("线程初始化->准备 主预览 数据...")); gPageName["P01"] = "主预览"; }break; case 2:{emit logMessage(QString("线程初始化->准备 屏蔽条件 数据...")); gPageName["P02"] = "屏蔽条件"; emit logMessage(QString("线程初始化->读取 UI_屏蔽界面文本_配置 文件...")); ShieldConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_屏蔽界面文本_配置.csv"); }break; case 3:{emit logMessage(QString("线程初始化->准备 油泵设备 数据...")); gPageName["P301"] = "油泵设备"; emit logMessage(QString("线程初始化->读取 UI_油泵界面启停条件_配置 文件...")); PumpConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_油泵界面启停条件_配置.csv"); }break; case 4:{emit logMessage(QString("线程初始化->准备 截割设备 数据...")); gPageName["P401"] = "截割设备"; emit logMessage(QString("线程初始化->读取 UI_截割界面启停条件_配置 文件")); CutConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_截割界面启停条件_配置.csv"); }break; case 5:{emit logMessage(QString("线程初始化->准备 装载设备 数据...")); gPageName["P501"] = "装载设备"; emit logMessage(QString("线程初始化->读取 UI_装载界面启停条件_配置 文件")); LoaderConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_装载界面启停条件_配置.csv"); }break; case 6:{emit logMessage(QString("线程初始化->准备 运输设备 数据...")); gPageName["P601"] = "运输设备"; emit logMessage(QString("线程初始化->读取 UI_运输界面启停条件_配置 文件")); TransportConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_运输界面启停条件_配置.csv"); }break; case 7:{emit logMessage(QString("线程初始化->准备 备用设备 数据...")); gPageName["P07"] = "备用设备"; emit logMessage(QString("线程初始化->读取 UI_备用界面启停条件_配置 文件")); StandbyConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_备用界面启停条件_配置.csv"); }break; case 8:{emit logMessage(QString("线程初始化->准备 故障记录 数据...")); gPageName["P08"] = "故障记录"; emit logMessage(QString("线程初始化->读取 UI_报警内容文本_配置 文件")); QList FileData = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_报警内容文本_配置.csv"); emit logMessage(QString("线程初始化->解析 UI_报警内容文本_配置 文件")); for (int row = 1; row < FileData.size()-1; ++row) { bool ok1,ok2; uint8_t Dev = FileData.at(row)[0].toUInt(&ok1, 16); uint8_t Index = FileData.at(row)[1].toUInt(&ok2, 16); AlarmText[Dev][Index].TextColor = FileData.at(row)[2]; AlarmText[Dev][Index].AlarmText = FileData.at(row)[3] + "->" + FileData.at(row)[4]; AlarmText[Dev][Index].Troubleshoot = FileData.at(row)[5]; } }break; case 9:{emit logMessage(QString("线程初始化->准备 遥控测试 数据...")); gPageName["P09"] = "遥控测试"; }break; case 10:{emit logMessage(QString("线程初始化->准备 自动智能 数据...")); gPageName["P10"] = "自动智能"; }break; case 11:{emit logMessage(QString("线程初始化->准备 绝缘检测 数据...")); gPageName["P11"] = "绝缘检测"; }break; case 12:{emit logMessage(QString("线程初始化->准备 网络拓扑 数据...")); gPageName["P12.00"] = "网络拓扑"; gPageName["P12.01"] = "硬件IO 1"; gPageName["P12.02"] = "硬件IO 2"; gPageName["P12.03"] = "硬件IO 3"; gPageName["P12.04"] = "硬件IO 4"; gPageName["P12.05"] = "硬件IO 3"; gPageName["P12.06"] = "操作箱 1"; gPageName["P12.07"] = "操作箱 2"; gPageName["P12.08"] = "操作箱 3"; gPageName["P12.09"] = "操作箱 4"; }break; case 13:{emit logMessage(QString("线程初始化->准备 本地控制 数据...")); gPageName["P13"] = "本地控制"; }break; case 14:{emit logMessage(QString("线程初始化->准备 随机图册 数据...")); gPageName["P14"] = "随机图册"; }break; case 15:{emit logMessage(QString("线程初始化->准备 参数设置 数据...")); gPageName["P15"] = "参数设置"; }break; case 16:{emit logMessage(QString("线程初始化->准备 系统设置 数据...")); gPageName["P16"] = "系统设置"; }break; } m_initialized = true; emit initializationComplete(m_pageIndex, initData); emit createWindowRequest(m_pageIndex); } // LaunchPage类实现 LaunchPage::LaunchPage(QWidget *parent) : QWidget(parent) , ui(new Ui::LaunchPage) { ui->setupUi(this); setWindowFlag(Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground, true); #if CONFIG_EN_SUB_THREAD LP_ST.start(); #endif QTimer::singleShot(10, this, &LaunchPage::createPages); } LaunchPage::~LaunchPage() { #if CONFIG_EN_SUB_THREAD LP_ST.KillThread(); #endif // 清理所有工作线程 for (QThread *thread : workerThreads) { if (thread && thread->isRunning()) { thread->quit(); if (!thread->wait(500)) { thread->terminate(); } } delete thread; } delete ui; // 清理TTS if (tts) { tts->stop(); delete tts; } } void LaunchPage::AddLogInfo(QString Str) { Sleep_ms(1); ui->LoaderList->addItem(Str); ui->LoaderList->setCurrentRow(ui->LoaderList->count() - 1); //qDebug()<setIcon(icon); trayIcon->setToolTip("郑煤机-掘锚一体机"); trayIcon->show(); minimizeAction = new QAction("隐藏", this); connect(minimizeAction, &QAction::triggered, this, &LaunchPage::hide); restoreAction = new QAction("还原", this); connect(restoreAction, &QAction::triggered, this, &LaunchPage::showNormal); quitAction = new QAction("退出", this); connect(quitAction, &QAction::triggered, this, [this]() { qApp->quit(); }); trayIconMenu = new QMenu(this); trayIconMenu->addAction(minimizeAction); trayIconMenu->addAction(restoreAction); trayIconMenu->addSeparator(); trayIconMenu->addAction(quitAction); trayIcon->setContextMenu(trayIconMenu); connect(trayIcon, &QSystemTrayIcon::activated, this, [this](QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::Trigger) { this->showNormal(); } }); } void LaunchPage::createPages() { WinInit(); /* ============= 1. 只把主窗口 show 出来 ============= */ AddLogInfo("窗口创建->正在创建公共窗口..."); pubWin = new P00_PublicPage(this); pubWin->setObjectName("pubWin"); pubWin->setStyleSheet("background-color: transparent;"); AddLogInfo("窗口布局->正在共享窗口布局..."); // 获取PublicWin中的scrollArea scrollArea = pubWin->findChild("scrollArea"); isNewScrollArea = false; if (!scrollArea) { // 如果找不到scrollArea,创建新的并添加到PublicWin布局 scrollArea = new QScrollArea(pubWin); scrollArea->setObjectName("scrollArea"); isNewScrollArea = true; qDebug() << "创建新的scrollArea"; } AddLogInfo("窗口属性->正在设置窗口属性..."); scrollArea->setStyleSheet("background-color: transparent; border: none;"); // 配置滚动区域属性 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scrollArea->setWidgetResizable(false); // 关键:保持内容原始尺寸以实现横向滚动 scrollArea->setStyleSheet("border: none;"); // 创建容器部件 - 用于承载水平排列的窗口 container = new QWidget(); container->setObjectName("scrollContainer"); container->setStyleSheet("background-color: transparent;"); // 使用水平布局 hLayout = new QHBoxLayout(container); hLayout->setSpacing(10); // 窗口之间的间距 hLayout->setContentsMargins(0, 0, 0, 0); // 容器内边距 // 初始化窗口计数器 windowsCreated = 1; currentLoadingIndex = 1; // 当前加载的窗口索引 // 启动顺序加载 startNextWindowLoading(); } void LaunchPage::startNextWindowLoading() { if (currentLoadingIndex < 17) { AddLogInfo(QString("开始加载第 %1 个窗口").arg(currentLoadingIndex)); // 创建线程和工作器 QThread *thread = new QThread(this); WindowWorker *worker = new WindowWorker(currentLoadingIndex); worker->moveToThread(thread); // 连接线程信号槽 connect(thread, &QThread::finished, worker, &WindowWorker::deleteLater); connect(thread, &QThread::finished, thread, &QThread::deleteLater); connect(thread, &QThread::started, worker, &WindowWorker::initialize); connect(worker, &WindowWorker::logMessage, this, &LaunchPage::AddLogInfo); // 连接窗口创建请求信号到主线程的创建函数 connect(worker, &WindowWorker::createWindowRequest,this, &LaunchPage::createWindowInMainThread,Qt::QueuedConnection); // 保存初始化数据 connect(worker, &WindowWorker::initializationComplete,this, &LaunchPage::storeWindowData); // 关键修改:使用单次连接,并携带当前索引作为参数 QMetaObject::Connection* conn = new QMetaObject::Connection; int currentIndex = currentLoadingIndex; // 保存当前索引 *conn = connect(this, &LaunchPage::windowCreationCompleted, this, [this, conn, currentIndex]() { disconnect(*conn); delete conn; // 只有当处理的是当前索引时才递增 if (currentIndex == this->currentLoadingIndex) { this->currentLoadingIndex++; this->startNextWindowLoading(); } }, Qt::QueuedConnection); workerThreads.append(thread); thread->start(); } else { // 所有窗口加载完成后的处理 AddLogInfo("所有窗口加载完成"); // 隐藏滚动条(如果需要) scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 水平滚动条按需显示 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 隐藏垂直滚动条 // 设置滚动区域的内容部件 scrollArea->setWidget(container); // 确保scrollArea被正确添加到PublicWin中 if (isNewScrollArea) { // 为PublicWin设置布局(如果没有) if (!pubWin->layout()) { QVBoxLayout *mainLayout = new QVBoxLayout(pubWin); mainLayout->setContentsMargins(0, 0, 0, 0); pubWin->setLayout(mainLayout); } // 将滚动区域添加到布局 pubWin->layout()->addWidget(scrollArea); } // 显示主窗口 ui->LoaderList->clear(); ui->LoaderList->setStyleSheet("border-image: url(:/Frames/null.png);"); pubWin->show(); } } void LaunchPage::createWindowInMainThread(int pageIndex) { if (pageIndex < 0 || pageIndex >= 17) { AddLogInfo(QString("无效的窗口索引: %1,跳过创建").arg(pageIndex)); return; } QWidget *window = nullptr; // 在主线程中创建窗口 switch (pageIndex) { case 1: {window = new P01_MianPage(container); AddLogInfo("窗口创建->P01_MianPage窗口...");}break; case 2: {window = new P02_ShieldPage(container); AddLogInfo("窗口创建->P02_ShieldPage窗口...");}break; case 3: {window = new P301_PumpPage(container); AddLogInfo("窗口创建->P301_PumpPage窗口...");}break; case 4: {window = new P401_CuttingPage(container); AddLogInfo("窗口创建->P401_CuttingPage窗口...");}break; case 5: {window = new P501_LoaderPage(container); AddLogInfo("窗口创建->P501_LoaderPage窗口...");}break; case 6: {window = new P601_TransportPage(container); AddLogInfo("窗口创建->P601_TransportPage窗口...");}break; case 7: {window = new P07_CylinderPage(container); AddLogInfo("窗口创建->P07_CylinderPage窗口...");}break; case 8: {window = new P08_AlarmPage(container); AddLogInfo("窗口创建->P08_AlarmPage窗口...");}break; case 9: { switch (PageConfig_RemoteIndex) { case 1:{window = new P901_RemotePage(container);AddLogInfo("窗口创建->P901_RemotePage窗口...");}break; case 2:{window = new P902_RemotePage(container);AddLogInfo("窗口创建->P902_RemotePage窗口...");}break; default:{window = new P901_RemotePage(container);AddLogInfo("窗口创建->P901_RemotePage窗口...");}break; } }break; case 10: {window = new P10_IntelligentPage(container);AddLogInfo("窗口创建->P10_IntelligentPage窗口...");}break; case 11: {window = new P11_IsolationPage(container); AddLogInfo("窗口创建->P11_IsolationPage窗口...");}break; case 12: {window = new P12_NetworkPage(container); AddLogInfo("窗口创建->P12_NetworkPage窗口...");}break; case 13: {window = new P13_InsPage(container); AddLogInfo("窗口创建->P13_InsPage窗口...");}break; case 14: {window = new P14_AtlasPage(container); AddLogInfo("窗口创建->P14_AtlasPage窗口...");}break; case 15: {window = new P15_ParameterPage(container); AddLogInfo("窗口创建->P15_ParameterPage窗口...");}break; case 16: {window = new P16_SettingPage(container); AddLogInfo("窗口创建->P16_SettingPage窗口...");}break; default: {AddLogInfo(QString("无效的窗口索引: %1").arg(pageIndex));}return; } if (window) { window->setObjectName(QString("window_%1").arg(pageIndex)); window->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); hLayout->addWidget(window); window->show(); // 直接比较当前加载索引与页面索引 if (pageIndex != currentLoadingIndex) { qCritical()<<"窗口载入失败!"<LoaderList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->LoaderList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ConfigFiles().SystemConfig(); TrayIconInit(); gPageIndexStr = "P01"; // 创建TTS实例 ttsManager = new TTSManager(this); AddLogInfo("环境检测->正在判断是否具有语音播报能力..."); tts = new QTextToSpeech(this); tts->setLocale(QLocale("zh_CN")); tts->setRate(0.0); tts->setPitch(1.0); tts->setVolume(1.0); qDebug() << "可用语音列表:"; for (const QVoice &v : tts->availableVoices()) { qDebug() << v.name(); } connect(tts, &QTextToSpeech::stateChanged, [](QTextToSpeech::State s){ if (s == QTextToSpeech::Ready) qDebug() << "TTS ready"; }); }