Files
EJM_Display/LaunchPage.cpp
2025-10-16 17:40:00 +08:00

380 lines
15 KiB
C++
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.

#include "LaunchPage.h"
#include "ui_LaunchPage.h"
#include <PublicFunctions/Basic.h>
#include <QTimer>
#include <QDebug>
#include <QMetaObject>
#if CONFIG_EN_SUB_THREAD
#include <Threads/SubThread.h>
SubThread LP_ST;
#endif
// WindowWorker类实现
void WindowWorker::initialize()
{
// 执行耗时的数据初始化工作
QVariant initData;
// 根据不同页面索引准备不同的数据
switch(m_pageIndex) {
case 1:{emit logMessage(QString("线程初始化->准备 主预览 数据..."));
}break;
case 2:{emit logMessage(QString("线程初始化->准备 屏蔽条件 数据..."));
emit logMessage(QString("线程初始化->读取 UI_屏蔽界面文本_配置 文件..."));
ShieldConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_屏蔽界面文本_配置.csv");
}break;
case 3:{emit logMessage(QString("线程初始化->准备 油泵设备 数据..."));
emit logMessage(QString("线程初始化->读取 UI_油泵界面启停条件_配置 文件..."));
PumpConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_油泵界面启停条件_配置.csv");
}break;
case 4:{emit logMessage(QString("线程初始化->准备 截割设备 数据..."));
emit logMessage(QString("线程初始化->读取 UI_截割界面启停条件_配置 文件"));
CutConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_截割界面启停条件_配置.csv");
}break;
case 5:{emit logMessage(QString("线程初始化->准备 装载设备 数据..."));
emit logMessage(QString("线程初始化->读取 UI_装载界面启停条件_配置 文件"));
LoaderConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_装载界面启停条件_配置.csv");
}break;
case 6:{emit logMessage(QString("线程初始化->准备 运输设备 数据..."));
emit logMessage(QString("线程初始化->读取 UI_运输界面启停条件_配置 文件"));
TransportConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_运输界面启停条件_配置.csv");
}break;
case 7:{emit logMessage(QString("线程初始化->准备 备用设备 数据..."));
emit logMessage(QString("线程初始化->读取 UI_备用界面启停条件_配置 文件"));
StandbyConditionConfigFile = ConfigFiles().ReadFile_Csv(ConfigurationPath + "画面配置/UI_备用界面启停条件_配置.csv");
}break;
case 8:{emit logMessage(QString("线程初始化->准备 故障记录 数据..."));
emit logMessage(QString("线程初始化->读取 UI_报警内容文本_配置 文件"));
QList<QStringList> 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("线程初始化->准备 遥控测试 数据..."));
}break;
case 10:{emit logMessage(QString("线程初始化->准备 自动智能 数据..."));
}break;
case 11:{emit logMessage(QString("线程初始化->准备 绝缘检测 数据..."));
}break;
case 12:{emit logMessage(QString("线程初始化->准备 网络拓扑 数据..."));
}break;
case 13:{emit logMessage(QString("线程初始化->准备 本地控制 数据..."));
}break;
case 14:{emit logMessage(QString("线程初始化->准备 随机图册 数据..."));
}break;
case 15:{emit logMessage(QString("线程初始化->准备 参数设置 数据..."));
}break;
case 16:{emit logMessage(QString("线程初始化->准备 系统设置 数据..."));
}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()<<Str;
}
void LaunchPage::TrayIconInit()
{
QIcon icon = QIcon("logo.png");
trayIcon = new QSystemTrayIcon(this);
trayIcon->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<QScrollArea*>("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()<<"窗口载入失败!"<<pageIndex<<currentLoadingIndex;
}
}
emit windowCreationCompleted();
}
void LaunchPage::storeWindowData(int pageIndex, const QVariant &data)
{
windowData[pageIndex] = data;
}
void LaunchPage::WinInit()
{
ui->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";
});
}