排障窗口增加数值监控。

在窗口数量大于4时启用窗口扩大按钮。
日志去除多余功能。
This commit is contained in:
2025-10-14 20:43:33 +08:00
parent 64ba329946
commit fcc512fd61
9 changed files with 237 additions and 58 deletions
+2 -1
View File
@@ -66,6 +66,7 @@ signals:
//排障
void runCommand_addBtn(const QString& btnName, const QString& tip, const QString& uuid);
void runCommand_addPlcValueViewer(const QString& groupName,std::vector<std::pair<QString, int>> viewerNameAndAddress);
void runCommand_refeshPlcValueViewer(int address,int value);
};
#pragma once
+9 -2
View File
@@ -120,7 +120,14 @@ public:
_serviceManager->_triggerManager->registerCallback(address[i].triggerAddr, address[i].triggerValue, [this, i](int triggerPos, int triggerValue, QByteArray& byteArray) {
evaluate(i, byteArray);}, "");
}
for (int i = 0; i < address.size(); i++) {
_serviceManager->_triggerManager->registerPlcValueViewer(viewerNameIN + "_" + QString::number(i),
{ {"触发",address[i].triggerAddr },
{"反馈",address[i].completeAddr.toInt()},
{"数值1",address[i].valueOffsetAddr},
{"数值2",address[i].valueOffsetAddr + 2},
{"数值3",address[i].valueOffsetAddr + 4} });
}
}
//获取图片并进行检测
void evaluate(int batteryOffset, QByteArray& byteArray) {
@@ -129,7 +136,7 @@ public:
auto camera = _serviceManager->_cameraManager->getCamera(cameraName);//获取相机
camera->clearCache();//清除缓存
std::shared_ptr <detData> data = _serviceManager->_detDataManager->createDetData(
QString::number(address[batteryOffset].triggerAddr), sn, 1, camera->config.oriSaveFormat);//创建数据包
QString::fromStdString(cameraName), sn, 1, camera->config.oriSaveFormat);//创建数据包
camera->captureImage(data);//拍照
data->saveObjectName = saveObjectName;
generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号
+1
View File
@@ -165,4 +165,5 @@ void triggerManager::decodeCameraCMD(readAllStruct& _struct, QByteArray byte)
}
checkCallback(_struct,byte);
checkUnionCallback(_struct, byte);
checkPlcValueViewer(_struct, byte);
}
+21
View File
@@ -392,6 +392,27 @@ public:
return str.toStdString();
}
//SUB
void registerPlcValueViewer(const QString& groupName, const std::vector<std::pair<QString, int>>& viewerNameAndAddress) {
for (auto& data : viewerNameAndAddress) {
if (data.second < 0)continue;
plcValueViewerDatas.push_back({ data.second, -1 });
}
emit bridge->runCommand_addPlcValueViewer(groupName, viewerNameAndAddress);
}
void checkPlcValueViewer(readAllStruct& _struct, QByteArray& byteArray) {
QMutexLocker locer(&mutex);
for (auto& data : plcValueViewerDatas) {
int checkPos = (data.first - _struct.startPos) * 2 + 1;
if(checkPos< byteArray.size() && checkPos >= 0)
if (byteArray.at(checkPos) != data.second) {
data.second = byteArray.at(checkPos);
emit bridge->runCommand_refeshPlcValueViewer(data.first, data.second);
}
}
}
std::vector<std::pair<int, int>>plcValueViewerDatas;
private:
QElapsedTimer lostConnectionCountTimer,lostConnectionRePrintTimer;
qtFuncBridge* bridge;
+3 -1
View File
@@ -137,8 +137,10 @@ public:
emit bridge->runCommand_addBtn("全部触发", tips, allTriggerUuid);
QString allClearUuid = QUuid::createUuid().toString();
emit bridge->runCommand_addBtn("全部清零", setZeroTips, allClearUuid);
emit bridge->runCommand_addBtn("触发全部清零", setZeroTips, allClearUuid);
presets[allClearUuid] = setZeroCommands;
}
}
+2 -40
View File
@@ -31,9 +31,9 @@
//行数上限
const int MAX_LOGWIDGET_LINES = 1000;
//内存中存储的消息数量上限
const int MAX_STORED_MESSAGES = 5000;
const int MAX_STORED_MESSAGES = 8000;
//批量处理延迟时间(毫秒)
const int BATCH_UPDATE_DELAY = 100;
const int BATCH_UPDATE_DELAY = 300;
class logWidget : public QWidget {
Q_OBJECT
@@ -239,7 +239,6 @@ public:
[this, index]() { applyFilters(index); });
// 连接功能按钮
connect(saveBtn, &QPushButton::clicked, [this, index]() { saveLogToFile(index); });
connect(clearBtn, &QPushButton::clicked, [this, index]() { clearLog(index); });
connect(autoScrollBtn, &QPushButton::toggled, [this, index](bool checked) {
filterStates[index].autoScroll = checked;
@@ -385,43 +384,6 @@ private:
scrollBar->setValue(scrollBar->maximum());
}
// 保存日志到文件
void saveLogToFile(int index) {
QMutexLocker globalLocker(&globalMutex);
if (filterStates.find(index) == filterStates.end()) return;
FilterState& state = filterStates[index];
QString fileName = QFileDialog::getSaveFileName(
this,
"保存日志文件",
QString("log_%1.txt").arg(getCurrentDate()),
"文本文件 (*.txt);;所有文件 (*.*)"
);
if (!fileName.isEmpty()) {
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
out.setCodec("UTF-8");
// 复制当前显示的内容以避免在写入时内容发生变化
QString content;
{
QMutexLocker stateLocker(&state.mutex);
content = state.textWidget->toPlainText();
}
out << content;
file.close();
QMessageBox::information(this, "成功", "日志已保存到: " + fileName);
} else {
QMessageBox::warning(this, "错误", "无法保存文件: " + fileName);
}
}
}
// 清空日志
void clearLog(int index) {
QMutexLocker globalLocker(&globalMutex);
+125 -3
View File
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
@@ -302,6 +302,18 @@ class ImageWidget : public QWidget {
public:
QComboBox switchBox;
QMutex switchViewerMutex;
//缩放状态相关
QPushButton* zoombtn;
bool isZoomed = false;
QSize originalSize;
QPoint originalPosition;
QGridLayout* parentGridLayout = nullptr;
int originalRow = -1;
int originalColumn = -1;
int originalRowSpan = 1;
int originalColumnSpan = 1;
ImageWidget(QWidget* parent = nullptr) : QWidget(parent) {
qRegisterMetaType<cv::Mat>("cv::Mat");
QVBoxLayout* layout = new QVBoxLayout(this);
@@ -324,6 +336,28 @@ public:
/* auto spaceItem = new QSpacerItem(100, 1);
hLayout->addSpacerItem(spaceItem);*/
zoombtn = new QPushButton();
zoombtn->setFixedSize(16, 16);
zoombtn
->setStyleSheet(
R"(
QPushButton {
background-color: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 3px;
}
QPushButton:hover {
background-color: rgba(0, 0, 0, 0.7);
border: 1px solid rgba(255, 255, 255, 0.5);
}
)"
);
zoombtn->setIcon(QPixmap(":icon/icon/fullscreen.png"));
zoombtn->setToolTip("放大窗口");
hLayout->addWidget(zoombtn);
connect(zoombtn, &QPushButton::clicked, this, &ImageWidget::toggleZoom);
label = new QLabel(u8"相机标签");
label->setAlignment(Qt::AlignLeft);
label->setFont(font);
@@ -387,6 +421,16 @@ public:
map.insert(name, QPixmap());
switchBox.addItem(name);
}
//设置父网格布局和位置信息
void setParentGridLayout(QGridLayout* gridLayout, int row, int column, int rowSpan, int columnSpan) {
parentGridLayout = gridLayout;
originalRow = row;
originalColumn = column;
originalRowSpan = rowSpan;
originalColumnSpan = columnSpan;
originalSize = this->size();
}
public slots:
//combobox切换槽
void switchViewType(QString name)
@@ -455,6 +499,71 @@ public slots:
viewer->setImg(px);
}
}
//缩放
void toggleZoom() {
if (!parentGridLayout) return;
if (!isZoomed) {
zoomIn();// 放大
}
else {
zoomOut();//缩小
}
}
// 放大窗口
void zoomIn() {
if (isZoomed) return;
if (!parentGridLayout) return;
// 保存原始状态
originalSize = this->size();
// 在网格布局中重新放置,占据更多空间
parentGridLayout->removeWidget(this);
//计算父布局的总行数和总列数
int maxRowSpan = parentGridLayout->rowCount();// 父布局总行数
int maxColSpan = parentGridLayout->columnCount();// 父布局总列数
//放大后的跨度
int zoomColSize = maxColSpan - 1;
int zoomRowSize = maxRowSpan - 1;
if (originalRow >= zoomRowSize -1 || originalColumn >= zoomColSize -1) {
int x = qMax(0, originalRow - (zoomRowSize - 1));
int y = qMax(0, originalColumn - (zoomColSize - 1));
parentGridLayout->addWidget(this, x, y, zoomRowSize, zoomColSize);
}
else{
parentGridLayout->addWidget(this, originalRow, originalColumn, zoomRowSize, zoomColSize);
}
this->raise();
// 更新按钮状态
isZoomed = true;
zoombtn->setIcon(QIcon(":/icon/icon/fullscreen-exit.png"));
zoombtn->setToolTip("缩小窗口");
// 强制更新布局
parentGridLayout->update();
this->update();
}
// 缩小窗口
void zoomOut() {
if (!isZoomed) return;
// 恢复原始布局位置
parentGridLayout->removeWidget(this);
parentGridLayout->addWidget(this, originalRow, originalColumn, originalRowSpan, originalColumnSpan);
//更新按钮状态
isZoomed = false;
zoombtn->setIcon(QIcon(":/icon/icon/fullscreen.png"));
zoombtn->setToolTip("放大窗口");
//强制更新布局
parentGridLayout->update();
this->update();
}
protected:
void wheelEvent(QWheelEvent* event) override {
if (event->modifiers() & Qt::ControlModifier) {
@@ -547,19 +656,32 @@ public:
ImageWidgetList.push_back(ImageView);
map.insert({ windowName,ImageView });
ImageView->setTitle(windowName);
if (xPos == -1 || yPos == -1)
if (xPos == -1 || yPos == -1){
Layout->addWidget(ImageView);
else
}
else {
// 指定位置布局
Layout->addWidget(ImageView, yPos, xPos);
ImageView ->setParentGridLayout(Layout, yPos, xPos, 1, 1);
}
for (auto& viewer : viewers)
ImageView->createViewer(QString::fromStdString(viewer));
if (ImageView->parentGridLayout->rowCount() < 3 && ImageView->parentGridLayout->columnCount() < 3) {
ImageView->zoombtn->hide();
}
return ImageView;
}
QGridLayout* Layout = new QGridLayout();
ImageWidgetManager()
{
this->setLayout(Layout);
Layout->setContentsMargins(0, 0, 0, 0);
// 设置布局属性,允许窗口缩放
/*Layout->setColumnStretch(0, 1);
Layout->setColumnStretch(1, 1);
Layout->setColumnStretch(2, 1);*/
}
~ImageWidgetManager()
{
+68 -11
View File
@@ -2,6 +2,50 @@
#include <global.h>
#include <nlohmannJson.hpp>
#include <qlayout.h>
class plcValueViewer :public QWidget{
public:
QPalette palette;
QFont font1 = QFont("微软雅黑", 12, QFont::Bold);
QFont font2 = QFont("微软雅黑", 10, QFont::Bold);
QFont font3 = QFont("微软雅黑", 6, QFont::Bold);
plcValueViewer(const QString& groupNameIN,
const std::vector<std::pair<QString, int>>& viewerNameAndAddress,
QMap<int, std::vector<QLabel*>>& plcViwerLineedits)
:groupName(groupNameIN){
palette.setColor(QPalette::WindowText, Qt::white);
QLabel* groupNameLabel = new QLabel(groupNameIN);
groupNameLabel->setFont(font1);
groupNameLabel->setPalette(palette);
layout->addWidget(groupNameLabel);
for (auto& data : viewerNameAndAddress) {
plcViwerLineedits[data.second].push_back(addViewer(data.first));
}
widget->setMaximumHeight(100);
}
QLabel* addViewer(const QString& viewerName) {
map.insert(groupName + viewerName ,new QLabel("*"));
auto label = map[groupName + viewerName];
label->setFont(font2);
label->setPalette(palette);
auto textLabel = new QLabel(viewerName);
textLabel->setFont(font3);
textLabel->setPalette(palette);
QVBoxLayout* viewerLayout = new QVBoxLayout();
viewerLayout->addWidget(label,Qt::AlignCenter);
viewerLayout->addWidget(textLabel, Qt::AlignCenter);
layout->addLayout(viewerLayout);
return label;
}
QString groupName = "";
QWidget* widget = new QWidget();
QHBoxLayout* layout = new QHBoxLayout(widget);
QMap<QString, QLabel*> map;
};
class runCommandWidget : public QDialog {
Q_OBJECT
@@ -9,17 +53,20 @@ public:
explicit runCommandWidget(QWidget* parent = nullptr)
: QDialog(parent) {
this->setWindowTitle("执行命令");
this->resize(400, 800);
//setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint); // 去掉边框 //现在、、
//setAttribute(Qt::WA_TranslucentBackground); // 背景透明
this->setObjectName("JsonParamTableEditor");
this->setStyleSheet(QString("QDialog#JsonParamTableEditor {background-color: rgb(%1);border: 2px solid #000000;border-radius: 6px;}").arg(sColor_Blue));
this->setObjectName("runCommandWidget");
this->setStyleSheet(QString("QDialog#runCommandWidget {background-color: rgb(%1);border: 2px solid #000000;border-radius: 6px;}").arg(sColor_Blue));
btnWidgets = new QListWidget(this);
btnWidgets->setStyleSheet("background: transparent;");
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(btnWidgets);
this->setFixedSize(sizeX, sizeY);
plcValueViewerLayout = new QVBoxLayout();
//plcValueViewerLayout->setStyleSheet("background: transparent;");
QGridLayout* layout = new QGridLayout(this);
layout->addWidget(btnWidgets, 0, 0);
layout->addLayout(plcValueViewerLayout, 0, 1);
this->setFixedWidth(sizeX);
}
signals:
@@ -28,9 +75,8 @@ signals:
public slots:
void addBtn(const QString& btnName, const QString& tip, const QString& uuid) {
QListWidgetItem* item = new QListWidgetItem(btnWidgets);
item->setSizeHint(QSize(sizeX - 30, 30));
btnWidgets->addItem(item);
fancyButtonText* funcBtn = new fancyButtonText(btnName, sizeX - 30, 30, tip);
fancyButtonText* funcBtn = new fancyButtonText(btnName,0,0, tip);
btnWidgets->setItemWidget(item, funcBtn);
connect(funcBtn, &fancyButtonText::clicked, this, [this, uuid]() {
QMessageBox::StandardButton reply;
@@ -45,8 +91,19 @@ public slots:
}
});
}
void addPlcValueViewer(const QString& groupName,std::vector<std::pair<QString, int>> viewerNameAndAddress) {
auto widget = new plcValueViewer(groupName, viewerNameAndAddress, plcViwerLineedits);
plcValueViewerLayout->addWidget(widget->widget,Qt::AlignTop);
}
void refreshPlcValueViewer(int address, int value) {
for (auto& lineedit : plcViwerLineedits[address]) {
lineedit->setText(QString::number(value));
}
}
private:
int sizeX = 300, sizeY = 500;
int sizeX = 1000, sizeY = 500;
QListWidget* btnWidgets;
QVBoxLayout* plcValueViewerLayout;
QMap<int, std::vector<QLabel*>>plcViwerLineedits;
};
#pragma once
+6
View File
@@ -160,6 +160,10 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge*
QObject::connect(_MainWindow->_displayWidget->_runCommandWidget,
&runCommandWidget::excuteCommandPreset,
[=](QString uuid) {_core->_backEnd.backend->excuteCliCommandPreset(uuid); });
QObject::connect(bridge, &qtFuncBridge::runCommand_addPlcValueViewer,
_MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::addPlcValueViewer);
QObject::connect(bridge, &qtFuncBridge::runCommand_refeshPlcValueViewer,
_MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::refreshPlcValueViewer);
}
int main(int argc, char* argv[])
@@ -206,6 +210,8 @@ int main(int argc, char* argv[])
qRegisterMetaType<initStatus>("initStatus");
qRegisterMetaType<cv::Mat>("mat");
qRegisterMetaType<std::vector<std::string>>("vectorstring");
qRegisterMetaType<std::vector<std::pair<QString, int>>>("constvpqi");
#pragma endregion
QApplication a(argc, argv);
_core.initDatabase(); // 初始化数据库