diff --git a/src/launcher/GUI/uiModule/uiModule_imageView.h b/src/launcher/GUI/uiModule/uiModule_imageView.h index 5e3943f..273d88c 100644 --- a/src/launcher/GUI/uiModule/uiModule_imageView.h +++ b/src/launcher/GUI/uiModule/uiModule_imageView.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include #include @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -302,6 +303,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"); QVBoxLayout* layout = new QVBoxLayout(this); @@ -324,6 +337,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 +422,32 @@ 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(); + + } + + void updateZoomButtonVisibility() { + if (parentGridLayout) { + int rowCount = parentGridLayout->rowCount(); + int columnCount = parentGridLayout->columnCount(); + + if (rowCount < 3 && columnCount < 3) { + zoombtn->hide(); + } + else { + zoombtn->show(); + } + } + } + public slots: //combobox切换槽 void switchViewType(QString name) @@ -455,6 +516,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,20 +673,35 @@ public: ImageWidgetList.push_back(ImageView); map.insert({ windowName,ImageView }); ImageView->setTitle(windowName); - if (xPos <= 0 || yPos <= 0) + 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)); - return ImageView; } + void updateAllZoomButtonsVisibility() { + for (auto* widget : ImageWidgetList) { + widget->updateZoomButtonVisibility(); + } + } + + 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() { @@ -578,72 +719,28 @@ public: } void adjustImageWidget() { if (ImageWidgetList.isEmpty()) return; - - // 清除现有布局中的所有部件 - QLayoutItem* item; - while ((item = Layout->takeAt(0)) != nullptr) { - if (item->widget()) { - Layout->removeWidget(item->widget()); - } - delete item; + std::vector> vec(Layout->rowCount(), std::vector(Layout->columnCount(),nullptr)); + for (auto& data : map) { + vec[data.second->originalRow][data.second->originalColumn] = data.second; } - - int total = ImageWidgetList.size(); - - // 计算最佳的网格布局行列数 - int cols = static_cast(std::ceil(std::sqrt(static_cast(total)))); - int rows = static_cast(std::ceil(static_cast(total) / cols)); - - // 创建一个二维数组来跟踪布局占用情况 - QVector> occupied(rows, QVector(cols, false)); - QVector> widgetSpans(rows, QVector(cols, QPoint(1, 1))); - - // 首先按基本网格放置部件 - int index = 0; - for (int row = 0; row < rows && index < total; ++row) { - for (int col = 0; col < cols && index < total; ++col) { - Layout->addWidget(ImageWidgetList[index], row, col); - occupied[row][col] = true; - index++; - } - } - - // 查找和填充空缺 - for (int row = 0; row < rows; ++row) { - for (int col = 0; col < cols; ++col) { - if (!occupied[row][col]) { - // 优先检查左侧部件是否可以横向扩展 - if (col > 0 && occupied[row][col-1]) { - int spanX = widgetSpans[row][col-1].x(); - int spanY = widgetSpans[row][col-1].y(); - QLayoutItem* item = Layout->itemAtPosition(row, col-1); - if (item && item->widget()) { - Layout->removeItem(item); - Layout->addWidget(item->widget(), row, col-1, spanY, spanX + 1); - widgetSpans[row][col-1].setX(spanX + 1); - occupied[row][col] = true; + for (int row = 0; row < vec.size(); row++) { + for (int col = 0; col < vec[row].size(); col++) { + if (vec[row][col] == nullptr) { + if (col > 0) { + if (vec[row][col - 1] != nullptr) { + Layout->span } } - // 如果左侧扩展不可行,尝试上方部件是否可以纵向扩展 - else if (row > 0 && occupied[row-1][col]) { - int spanX = widgetSpans[row-1][col].x(); - int spanY = widgetSpans[row-1][col].y(); - QLayoutItem* item = Layout->itemAtPosition(row-1, col); - if (item && item->widget()) { - Layout->removeItem(item); - Layout->addWidget(item->widget(), row-1, col, spanY + 1, spanX); - widgetSpans[row-1][col].setY(spanY + 1); - occupied[row][col] = true; - } + else { + } } } } - // 更新布局 Layout->update(); + updateAllZoomButtonsVisibility(); } - QGridLayout* Layout = new QGridLayout(); private: QMutex mutex; QList< ImageWidget*>ImageWidgetList;