#include "PhaseWindow.h" #include "ui_PhaseWindow.h" #include <iostream> #include <QTimer> #include <QDateTime> #include <QLabel> #include <QGroupBox> #include <QLineEdit> #include <QPushButton> #include <QHBoxLayout> #include <QDesktopWidget> #include <QThread> PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), ui(new Ui::PhaseWindow) { ui->setupUi(this); // 无边框 this->setWindowFlags(Qt::FramelessWindowHint); // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->availableGeometry(); resize(screenRect.width(), screenRect.height()); // 将窗口移动到左上角 move(0, 0); ui->minButt->move(screenRect.width() - 80, 10); ui->endButt->move(screenRect.width() - 140, 10); ui->startButt->move(screenRect.width() - 200, 10); ui->line->setGeometry(0, 59, screenRect.width(), 1); // 设置主体区域的大小和位置 ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); ui->logo->setText(QString("相位测量数据采集软件——%1").arg(SettingConfig::getInstance().MASTER == 1 ? "主" : "备")); if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); kafkaConsumer->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaConsumer->setTopic(SettingConfig::getInstance().KAFKA_CMD_TOPIC); kafkaConsumer->createConsumer(); kafkaConsumer->start(); connect(kafkaConsumer, &QKafkaConsumer::messageRecieved, this, &PhaseWindow::onPhaseCommandReceived); } httpReq = new HttpRequestController(this); // 1. 获取访问接口需要的token int retCode = this->initHttpToken(); if (retCode != 200) { QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); QTimer::singleShot(1000, qApp, SLOT(quit())); } // 2. 获取字典值:设备类型 // 3. 获取比相仪设备列表 initDeviceList(); // 4. 打开串口 for (int i = 0; i < deviceList.size(); i++) { PhaseDevice * devicePtr = deviceList.at(i); devicePtr->initSerialPort(); devicePtr->startWork(); QThread::msleep(100); } // 6. 绘制一个设备的多个通道数据面板 this->generateWidgetForDevice(); HttpServer::instance().run(QHostAddress::Any, SettingConfig::getInstance().SERVER_PORT); } PhaseWindow::~PhaseWindow() { delete ui; } void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { // 当前显示的设备编号 QString currentDevCode = ui->devSelect->currentData().toString(); // 如果不是当前设备的帧,直接返回 if (phaseData->devCode != currentDevCode) { return; } ui->labTm->setText(phaseData->timestamp.left(19)); // 更新所有通道BOX的值 for (int i = 0; i < phaseData->channelActive.size(); i++) { // 获取对应的通道BOX QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label ((QLabel *)channelBox->children().at(1))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); // 有效性 ((QLabel *)channelBox->children().at(2))->setText(phaseData->frameId); // 数据ID ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); // 测量数据值 } } void PhaseWindow::drawPhaseAllenOnPage(QString devCode, QVector<QStringList> channelAllenResultStr) { // 当前显示的设备编号 QString currentDevCode = ui->devSelect->currentData().toString(); // 如果不是当前设备的帧,直接返回 if (devCode != currentDevCode) { return; } // 更新所有通道BOX的值 for (int i = 0; i < channelAllenResultStr.size(); i++) { // 获取对应的通道BOX QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的label ((QLabel *)channelBox->children().at(7))->setText(channelAllenResultStr.at(i).at(0)); // tau=1 Allen ((QLabel *)channelBox->children().at(8))->setText(QString("(%1)").arg(channelAllenResultStr.at(i).at(1))); // tau=1 Count ((QLabel *)channelBox->children().at(10))->setText(channelAllenResultStr.at(i).at(2)); // tau=10 Allen ((QLabel *)channelBox->children().at(11))->setText(QString("(%1)").arg(channelAllenResultStr.at(i).at(3))); // tau=10 Count ((QLabel *)channelBox->children().at(13))->setText(channelAllenResultStr.at(i).at(4)); // tau=100 Allen ((QLabel *)channelBox->children().at(14))->setText(QString("(%1)").arg(channelAllenResultStr.at(i).at(5))); // tau=100 Count ((QLabel *)channelBox->children().at(16))->setText(channelAllenResultStr.at(i).at(6)); // tau=1000 Allen ((QLabel *)channelBox->children().at(17))->setText(QString("(%1)").arg(channelAllenResultStr.at(i).at(7))); // tau=1000 Count ((QLabel *)channelBox->children().at(19))->setText(channelAllenResultStr.at(i).at(8)); // tau=10000 Allen ((QLabel *)channelBox->children().at(20))->setText(QString("(%1)").arg(channelAllenResultStr.at(i).at(9))); // tau=10000 Count } } void PhaseWindow::generateWidgetForDevice() { // 获取设备数据 int channelNum = 16; QRect screenRect = QApplication::desktop()->screenGeometry(); ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); const QFont labelFont("微软雅黑", 10); for (int i = 0; i < channelNum; i++) { QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); group->setFont(QFont("微软雅黑", 12)); group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); QHBoxLayout * vbox = new QHBoxLayout(group); // index = 1 QLabel * validLabel = new QLabel(); validLabel->setText("-"); validLabel->setFont(labelFont); validLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(validLabel); // index = 2 QLabel * idLabel = new QLabel(); idLabel->setText("0000"); idLabel->setFont(labelFont); idLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(idLabel); // index = 3 QLabel * dataLabel = new QLabel(); dataLabel->setText("测量数据"); dataLabel->setFont(labelFont); dataLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(dataLabel); // index = 4 QLineEdit * dataValue = new QLineEdit(); dataValue->setFixedWidth(200); dataValue->setFont(labelFont); vbox->addWidget(dataValue); // index = 5 QLabel * perfLabel = new QLabel(); perfLabel->setText("稳定度"); perfLabel->setFont(labelFont); perfLabel->setStyleSheet("margin-left:50;"); vbox->addWidget(perfLabel); // index = 6 QLabel * oneLabel = new QLabel(); oneLabel->setText("Tau(s)=1"); oneLabel->setFont(labelFont); oneLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(oneLabel); // index = 7 QLabel * oneAllen = new QLabel(); oneAllen->setText("0.00"); oneAllen->setFont(labelFont); vbox->addWidget(oneAllen); // index = 8 QLabel * oneCount = new QLabel(); oneCount->setText("0"); oneCount->setFont(labelFont); vbox->addWidget(oneCount); // index = 9 QLabel * tenLabel = new QLabel(); tenLabel->setText("Tau(s)=10"); tenLabel->setFont(labelFont); tenLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(tenLabel); // index = 10 QLabel * tenAllen = new QLabel(); tenAllen->setText("0.00"); tenAllen->setFont(labelFont); vbox->addWidget(tenAllen); // index = 11 QLabel * tenCount = new QLabel(); tenCount->setText("0"); tenCount->setFont(labelFont); vbox->addWidget(tenCount); // index = 12 QLabel * hundLabel = new QLabel(); hundLabel->setText("Tau(s)=100"); hundLabel->setFont(labelFont); hundLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(hundLabel); // index = 13 QLabel * hundAllen = new QLabel(); hundAllen->setText("0.00"); hundAllen->setFont(labelFont); vbox->addWidget(hundAllen); // index = 14 QLabel * hundCount = new QLabel(); hundCount->setText("0"); hundCount->setFont(labelFont); vbox->addWidget(hundCount); // index = 15 QLabel * thouLabel = new QLabel(); thouLabel->setText("Tau(s)=1000"); thouLabel->setFont(labelFont); thouLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(thouLabel); // index = 16 QLabel * thouAllen = new QLabel(); thouAllen->setText("0.00"); thouAllen->setFont(labelFont); vbox->addWidget(thouAllen); // index = 17 QLabel * thouCount = new QLabel(); thouCount->setText("0"); thouCount->setFont(labelFont); vbox->addWidget(thouCount); // index = 18 QLabel * ttLabel = new QLabel(); ttLabel->setText("Tau(s)=10000"); ttLabel->setFont(labelFont); ttLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(ttLabel); // index = 19 QLabel * ttAllen = new QLabel(); ttAllen->setText("0.00"); ttAllen->setFont(labelFont); vbox->addWidget(ttAllen); // index = 20 QLabel * ttCount = new QLabel(); ttCount->setText("0"); ttCount->setFont(labelFont); vbox->addWidget(ttCount); QSpacerItem * hSpace = new QSpacerItem(20, 20); hSpace->changeSize(20, 20, QSizePolicy::Expanding); vbox->addItem(hSpace); group->setLayout(vbox); layout->addWidget(group); } } int PhaseWindow::initHttpToken() { QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, SettingConfig::getInstance().APP_KEY); return response.find("code")->toInt(); } void PhaseWindow::initDeviceList() { QJsonObject devListRes = httpReq->initDeviceList(SettingConfig::getInstance().DEV_TYPES, SettingConfig::getInstance().SYSTEM); if (devListRes.find("code")->toInt() == 200) { ui->devSelect->clear(); // 4. 将获取到的设备添加到下拉列表框中 QJsonArray devArray = devListRes.value("data").toArray(); for (int i = 0; i < devArray.size(); i++) { QJsonObject devItem = devArray.at(i).toObject(); ui->devSelect->addItem(devItem.value("deviceName").toString(), devItem.value("deviceNo").toString()); QString deviceId = devItem.value("deviceId").toString(); PhaseDevice * device = new PhaseDevice(this); deviceList.append(device); ConstCache::getInstance().deviceMap.insert(deviceId, device); device->setComName(devItem.value("linkComName").toString()); device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); device->setDevCode(devItem.value("deviceNo").toString()); device->setDeviceId(deviceId); connect(device, &PhaseDevice::sendDataToDraw, this, &PhaseWindow::drawPhaseDataOnPage); connect(device, &PhaseDevice::sendAllenToDraw, this, &PhaseWindow::drawPhaseAllenOnPage); this->getChannelList(deviceId); } // 5. 设置下拉框的样式 QStandardItemModel * model = qobject_cast<QStandardItemModel*>(ui->devSelect->model()); for (int i = 0; i < model->rowCount(); ++i) { QStandardItem * item = model->item(i); item->setSizeHint({ 0, 30 }); } } } void PhaseWindow::getChannelList(QString deviceId) { // 查询计数器的通道 QJsonObject response = httpReq->getPhaseChannelList(deviceId); if (response.value("code").toInt() == 200) { // 将通道绘制在界面上 QJsonArray channelArray = response.value("data").toArray(); for (int i = 0; i < channelArray.size(); i++) { // 接口返回的channel对象 QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID int channelNo = channelItem.value("channelNo").toInt(); // 添加到通道的集合中 key=channelId value=deviceId-channelNo if (channelNo > 0) { ConstCache::getInstance().channelMap.insert(channelId, QString("%1-%2").arg(deviceId).arg(channelNo)); } } } } void PhaseWindow::on_minButt_clicked() { setWindowState(Qt::WindowMinimized | windowState()); } void PhaseWindow::on_startButt_clicked() { int devSelected = ui->devSelect->currentIndex(); PhaseDevice * device = deviceList.at(devSelected); device->startWork(); } void PhaseWindow::on_endButt_clicked() { int devSelected = ui->devSelect->currentIndex(); PhaseDevice * device = deviceList.at(devSelected); device->stopWork(); } void PhaseWindow::on_devSelect_currentIndexChanged(int index) { // 清空显示的数据 if (ui->scrollContents->children().size() < 1) { return ; } for (int i = 0; i < 16; i++) { // 获取对应的通道BOX QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label ((QLabel *)channelBox->children().at(1))->setText("-"); // 有效性 ((QLabel *)channelBox->children().at(2))->setText("0000"); // 数据ID ((QLineEdit *)channelBox->children().at(4))->setText(""); // 测量数据值 ((QLabel *)channelBox->children().at(7))->setText("0.00"); // tau=1 Allen ((QLabel *)channelBox->children().at(8))->setText(QString("(%1)").arg(0)); // tau=1 Count ((QLabel *)channelBox->children().at(10))->setText("0.00"); // tau=10 Allen ((QLabel *)channelBox->children().at(11))->setText(QString("(%1)").arg(0)); // tau=10 Count ((QLabel *)channelBox->children().at(13))->setText("0.00"); // tau=100 Allen ((QLabel *)channelBox->children().at(14))->setText(QString("(%1)").arg(0)); // tau=100 Count ((QLabel *)channelBox->children().at(16))->setText("0.00"); // tau=1000 Allen ((QLabel *)channelBox->children().at(17))->setText(QString("(%1)").arg(0)); // tau=1000 Count ((QLabel *)channelBox->children().at(19))->setText("0.00"); // tau=10000 Allen ((QLabel *)channelBox->children().at(20))->setText(QString("(%1)").arg(0)); // tau=10000 Count } } void PhaseWindow::onPhaseCommandReceived(QJsonObject command) { // 缺少必须的字段deviceId 或 cmd 直接返回 if (command.contains("deviceId") == false || command.contains("cmd") == false) { return; } QString deviceId = command.value("deviceId").toString(); QString cmdType = command.value("cmd").toString(); // deviceId不属于子系统内的比相仪 直接返回 if (ConstCache::getInstance().deviceMap.contains(deviceId) == false) { return; } if (cmdType.toUpper() == "START" || cmdType.toUpper() == "STOP") { // 设备开始采集或者停止采集指令 PhaseDevice * devicePtr = ConstCache::getInstance().deviceMap.value(deviceId); if (devicePtr != nullptr) { if (cmdType.toUpper() == "START") { devicePtr->startWork(); } else if (cmdType.toUpper() == "STOP") { devicePtr->stopWork(); } } } else if (cmdType.toUpper() == "CLEAR") { // 清除通道的数据 通道级指令 QString channelId = command.value("channelId").toString(); if (ConstCache::getInstance().channelMap.contains(channelId) == true) { QString channelIndex = ConstCache::getInstance().channelMap.value(channelId); QString channelDevId = channelIndex.split("-").at(0); int channelNo = ((QString) channelIndex.split("-").at(1)).toInt(); PhaseDevice * devicePtr = ConstCache::getInstance().deviceMap.value(channelDevId); if (devicePtr != nullptr) { devicePtr->clearChannelPhaseData(channelNo); } } } }