404 lines
17 KiB
C++
404 lines
17 KiB
C++
#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("线程初始化->准备 主预览 数据..."));
|
||
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<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("线程初始化->准备 遥控测试 数据..."));
|
||
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()<<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";
|
||
});
|
||
}
|