Qt编程:基于QGraphView 工业级图像显示控件3

    在工业视觉检测软件中,图像显示控件是核心组件之一,需要满足高精度、高性能和丰富的交互功能需求。基于Qt编程:基于QGraphView 工业级图像显示控件2-CSDN博客进一步扩展,添加图层管理相关功能。

图层管理功能

下面将详细介绍 QIndustrialView 中图层管理功能的实现,包括所有相关方法和使用示例。

1. 图层管理数据结构

头文件新增内容

// LayerType 枚举 - 定义不同类型的图层
enum LayerType {
    ImageLayer,        // 基础图像层
    AnnotationLayer,   // 标注层(用于绘制标记、图形等)
    MeasurementLayer,  // 测量层(用于存放测量工具结果)
    TemporaryLayer     // 临时层(用于临时绘图)
};

// Layer 结构体 - 存储图层信息
struct Layer {
    int id;                     // 唯一ID
    QString name;               // 图层名称
    LayerType type;             // 图层类型
    QGraphicsItemGroup* group;  // Qt图形项组
    bool visible;               // 是否可见
    qreal opacity;              // 透明度(0.0-1.0)
    bool locked;                // 是否锁定(不可编辑)
    bool selectable;            // 是否可选
};

2. 完整图层管理接口

图层基础操作

/**
 * @brief 添加新图层
 * @param name 图层名称
 * @param type 图层类型
 * @param visible 是否可见
 * @param locked 是否锁定
 * @param selectable 是否允许选择
 * @return 图层ID,失败返回-1
 */
int addLayer(const QString &name, LayerType type, 
             bool visible = true, bool locked = false, 
             bool selectable = true);

/**
 * @brief 删除图层
 * @param layerId 图层ID
 * @return 是否成功
 */
bool removeLayer(int layerId);

/**
 * @brief 获取图层数量
 */
int layerCount() const;

/**
 * @brief 检查图层是否存在
 */
bool hasLayer(int layerId) const;

图层属性控制

/**
 * @brief 设置图层可见性
 */
bool setLayerVisible(int layerId, bool visible);

/**
 * @brief 设置图层透明度
 */
bool setLayerOpacity(int layerId, qreal opacity);

/**
 * @brief 锁定/解锁图层
 */
bool setLayerLocked(int layerId, bool locked);

/**
 * @brief 设置图层是否可选
 */
bool setLayerSelectable(int layerId, bool selectable);

/**
 * @brief 重命名图层
 */
bool renameLayer(int layerId, const QString &newName);

图层顺序控制

/**
 * @brief 将图层移到最顶层
 */
bool raiseLayerToTop(int layerId);

/**
 * @brief 将图层移到最底层
 */
bool lowerLayerToBottom(int layerId);

/**
 * @brief 上移一层
 */
bool raiseLayer(int layerId);

/**
 * @brief 下移一层
 */
bool lowerLayer(int layerId);

/**
 * @brief 移动到指定位置
 * @param newPosition 新位置(0-based)
 */
bool moveLayer(int layerId, int newPosition);

图层内容管理

/**
 * @brief 清空图层内容
 */
bool clearLayer(int layerId);

/**
 * @brief 清空所有非图像层
 */
void clearAllLayers();

/**
 * @brief 合并多个图层
 * @param targetLayerId 目标图层ID
 * @param layerIds 要合并的图层ID列表
 */
bool mergeLayers(int targetLayerId, const QList &layerIds);

图层查询接口

/**
 * @brief 获取图层组指针
 */
QGraphicsItemGroup* getLayer(int layerId) const;

/**
 * @brief 获取所有图层ID
 */
QList layerIds() const;

/**
 * @brief 获取图层名称
 */
QString layerName(int layerId) const;

/**
 * @brief 获取图层类型
 */
LayerType layerType(int layerId) const;

/**
 * @brief 获取图层可见性
 */
bool isLayerVisible(int layerId) const;

/**
 * @brief 获取图层透明度
 */
qreal layerOpacity(int layerId) const;

/**
 * @brief 获取图层锁定状态
 */
bool isLayerLocked(int layerId) const;

/**
 * @brief 获取图层可选状态
 */
bool isLayerSelectable(int layerId) const;

/**
 * @brief 查找包含指定项的图层
 */
int findLayerForItem(const QGraphicsItem *item) const;

3. 完整实现代码

图层管理核心实现

// 生成唯一图层ID
int QIndustrialView::generateLayerId() const {
    static int counter = 0;
    return ++counter;
}

// 添加图层实现
int QIndustrialView::addLayer(const QString &name, LayerType type, 
                            bool visible, bool locked, bool selectable) {
    // 检查名称是否已存在
    for (const Layer &layer : m_layers) {
        if (layer.name == name) {
            qWarning() << "Layer name already exists:" << name;
            return -1;
        }
    }

    Layer newLayer;
    newLayer.id = generateLayerId();
    newLayer.name = name;
    newLayer.type = type;
    newLayer.group = new QGraphicsItemGroup();
    newLayer.visible = visible;
    newLayer.opacity = 1.0;
    newLayer.locked = locked;
    newLayer.selectable = selectable;

    // 设置初始Z值
    newLayer.group->setZValue(m_layers.size());
    
    // 添加到场景
    m_scene->addItem(newLayer.group);
    m_layers.append(newLayer);

    // 设置初始属性
    newLayer.group->setVisible(visible);
    newLayer.group->setOpacity(newLayer.opacity);
    
    // 锁定图层时禁用所有子项
    if (locked) {
        setLayerLocked(newLayer.id, true);
    }

    emit layerAdded(newLayer.id);
    return newLayer.id;
}

// 设置图层锁定状态
bool QIndustrialView::setLayerLocked(int layerId, bool locked) {
    for (Layer &layer : m_layers) {
        if (layer.id == layerId) {
            if (layer.locked != locked) {
                layer.locked = locked;
                
                // 设置所有子项的flags
                QList items = layer.group->childItems();
                for (QGraphicsItem *item : items) {
                    if (locked) {
                        item->setFlags(QGraphicsItem::ItemIsSelectable);
                    } else {
                        item->setFlags(item->flags() | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
                    }
                }
                
                emit layerPropertyChanged(layerId);
                return true;
            }
            return false;
        }
    }
    return false;
}

// 合并图层实现
bool QIndustrialView::mergeLayers(int targetLayerId, const QList &layerIds) {
    QGraphicsItemGroup *targetGroup = getLayer(targetLayerId);
    if (!targetGroup) return false;

    // 收集所有要合并的项
    QList itemsToMerge;
    for (int layerId : layerIds) {
        if (layerId == targetLayerId) continue;
        
        QGraphicsItemGroup *group = getLayer(layerId);
        if (group) {
            itemsToMerge.append(group->childItems());
        }
    }

    // 合并项到目标图层
    for (QGraphicsItem *item : itemsToMerge) {
        item->setParentItem(targetGroup);
    }

    // 删除空图层
    for (int layerId : layerIds) {
        if (layerId != targetLayerId) {
            removeLayer(layerId);
        }
    }

    return true;
}

图层顺序控制实现

// 移动到最顶层
bool QIndustrialView::raiseLayerToTop(int layerId) {
    for (int i = 0; i < m_layers.size(); ++i) {
        if (m_layers[i].id == layerId) {
            if (i < m_layers.size() - 1) {
                Layer layer = m_layers.takeAt(i);
                m_layers.append(layer);
                updateLayerZValues();
                return true;
            }
            return false;
        }
    }
    return false;
}

// 更新所有图层的Z值
void QIndustrialView::updateLayerZValues() {
    for (int i = 0; i < m_layers.size(); ++i) {
        m_layers[i].group->setZValue(i);
    }
}

图层内容管理实现

// 清空图层内容
bool QIndustrialView::clearLayer(int layerId) {
    for (Layer &layer : m_layers) {
        if (layer.id == layerId) {
            QList items = layer.group->childItems();
            for (QGraphicsItem *item : items) {
                layer.group->removeFromGroup(item);
                delete item;
            }
            emit layerContentChanged(layerId);
            return true;
        }
    }
    return false;
}

// 查找包含指定项的图层
int QIndustrialView::findLayerForItem(const QGraphicsItem *item) const {
    if (!item) return -1;
    
    // 检查每个图层的子项
    for (const Layer &layer : m_layers) {
        if (layer.group->childItems().contains(const_cast(item))) {
            return layer.id;
        }
        
        // 检查是否是图层组本身
        if (layer.group == item) {
            return layer.id;
        }
    }
    
    return -1;
}

MainWindow中添加图层管理功能

基于前面实现的QIndustrialView图层管理功能,对应在MainWindow中添加相关的UI和操作实现。

1. 首先在MainWindow中添加UI元素

在头文件中添加成员变量和槽函数声明

// mainwindow.h
#include "QIndustrialView.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    // ... 其他现有代码
    
private slots:
    // 图层操作槽函数
    void onAddLayer();
    void onRemoveLayer();
    void onLayerSelected(int index);
    void onLayerVisibilityChanged(bool visible);
    void onLayerOpacityChanged(int value);
    void onLayerLockToggled(bool locked);
    void onLayerSelectableToggled(bool selectable);
    void onLayerRaise();
    void onLayerLower();
    void onLayerRaiseToTop();
    void onLayerLowerToBottom();
    void onLayerRename();
    
private:
    // 图层管理UI元素
    QToolBar* m_layerToolBar;
    QComboBox* m_layerCombo;
    QCheckBox* m_visibleCheck;
    QSlider* m_opacitySlider;
    QCheckBox* m_lockCheck;
    QCheckBox* m_selectableCheck;
    QToolButton* m_addLayerBtn;
    QToolButton* m_removeLayerBtn;
    QToolButton* m_raiseLayerBtn;
    QToolButton* m_lowerLayerBtn;
    QToolButton* m_raiseToTopBtn;
    QToolButton* m_lowerToBottomBtn;
    QToolButton* m_renameLayerBtn;
    
    // 图像视图
    QIndustrialView* m_industrialView;
    
    // 初始化图层UI
    void setupLayerUI();
    // 更新图层UI状态
    void updateLayerUI();
};

在MainWindow构造函数中初始化图层UI

// mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    // ... 其他初始化代码
    
    // 创建工业视图
    m_industrialView = new QIndustrialView(this);
    setCentralWidget(m_industrialView);
    
    // 初始化图层UI
    setupLayerUI();
    
    // 连接信号槽
    connect(m_industrialView, &QIndustrialView::layerAdded, this, &MainWindow::updateLayerUI);
    connect(m_industrialView, &QIndustrialView::layerPropertyChanged, this, &MainWindow::updateLayerUI);
    connect(m_industrialView, &QIndustrialView::layerContentChanged, this, &MainWindow::updateLayerUI);
}

void MainWindow::setupLayerUI()
{
    // 创建图层工具栏
    m_layerToolBar = addToolBar(tr("图层"));
    m_layerToolBar->setObjectName("layerToolBar");
    
    // 图层选择下拉框
    m_layerCombo = new QComboBox(this);
    m_layerCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
    connect(m_layerCombo, QOverload::of(&QComboBox::currentIndexChanged), 
            this, &MainWindow::onLayerSelected);
    m_layerToolBar->addWidget(new QLabel(tr("当前图层:")));
    m_layerToolBar->addWidget(m_layerCombo);
    
    // 添加图层按钮
    m_addLayerBtn = new QToolButton(this);
    m_addLayerBtn->setIcon(QIcon(":/icons/add_layer.png"));
    m_addLayerBtn->setToolTip(tr("添加图层"));
    connect(m_addLayerBtn, &QToolButton::clicked, this, &MainWindow::onAddLayer);
    m_layerToolBar->addWidget(m_addLayerBtn);
    
    // 删除图层按钮
    m_removeLayerBtn = new QToolButton(this);
    m_removeLayerBtn->setIcon(QIcon(":/icons/remove_layer.png"));
    m_removeLayerBtn->setToolTip(tr("删除图层"));
    connect(m_removeLayerBtn, &QToolButton::clicked, this, &MainWindow::onRemoveLayer);
    m_layerToolBar->addWidget(m_removeLayerBtn);
    
    // 图层属性控件
    m_layerToolBar->addSeparator();
    
    // 可见性复选框
    m_visibleCheck = new QCheckBox(tr("可见"), this);
    connect(m_visibleCheck, &QCheckBox::toggled, this, &MainWindow::onLayerVisibilityChanged);
    m_layerToolBar->addWidget(m_visibleCheck);
    
    // 不透明度滑块
    m_layerToolBar->addWidget(new QLabel(tr("不透明度:")));
    m_opacitySlider = new QSlider(Qt::Horizontal, this);
    m_opacitySlider->setRange(0, 100);
    m_opacitySlider->setValue(100);
    m_opacitySlider->setFixedWidth(80);
    connect(m_opacitySlider, &QSlider::valueChanged, this, &MainWindow::onLayerOpacityChanged);
    m_layerToolBar->addWidget(m_opacitySlider);
    
    // 锁定复选框
    m_lockCheck = new QCheckBox(tr("锁定"), this);
    connect(m_lockCheck, &QCheckBox::toggled, this, &MainWindow::onLayerLockToggled);
    m_layerToolBar->addWidget(m_lockCheck);
    
    // 可选复选框
    m_selectableCheck = new QCheckBox(tr("可选"), this);
    connect(m_selectableCheck, &QCheckBox::toggled, this, &MainWindow::onLayerSelectableToggled);
    m_layerToolBar->addWidget(m_selectableCheck);
    
    // 图层顺序按钮
    m_layerToolBar->addSeparator();
    
    // 上移一层
    m_raiseLayerBtn = new QToolButton(this);
    m_raiseLayerBtn->setIcon(QIcon(":/icons/layer_up.png"));
    m_raiseLayerBtn->setToolTip(tr("上移一层"));
    connect(m_raiseLayerBtn, &QToolButton::clicked, this, &MainWindow::onLayerRaise);
    m_layerToolBar->addWidget(m_raiseLayerBtn);
    
    // 下移一层
    m_lowerLayerBtn = new QToolButton(this);
    m_lowerLayerBtn->setIcon(QIcon(":/icons/layer_down.png"));
    m_lowerLayerBtn->setToolTip(tr("下移一层"));
    connect(m_lowerLayerBtn, &QToolButton::clicked, this, &MainWindow::onLayerLower);
    m_layerToolBar->addWidget(m_lowerLayerBtn);
    
    // 移到顶层
    m_raiseToTopBtn = new QToolButton(this);
    m_raiseToTopBtn->setIcon(QIcon(":/icons/layer_top.png"));
    m_raiseToTopBtn->setToolTip(tr("移到顶层"));
    connect(m_raiseToTopBtn, &QToolButton::clicked, this, &MainWindow::onLayerRaiseToTop);
    m_layerToolBar->addWidget(m_raiseToTopBtn);
    
    // 移到底层
    m_lowerToBottomBtn = new QToolButton(this);
    m_lowerToBottomBtn->setIcon(QIcon(":/icons/layer_bottom.png"));
    m_lowerToBottomBtn->setToolTip(tr("移到底层"));
    connect(m_lowerToBottomBtn, &QToolButton::clicked, this, &MainWindow::onLayerLowerToBottom);
    m_layerToolBar->addWidget(m_lowerToBottomBtn);
    
    // 重命名按钮
    m_renameLayerBtn = new QToolButton(this);
    m_renameLayerBtn->setIcon(QIcon(":/icons/rename.png"));
    m_renameLayerBtn->setToolTip(tr("重命名图层"));
    connect(m_renameLayerBtn, &QToolButton::clicked, this, &MainWindow::onLayerRename);
    m_layerToolBar->addWidget(m_renameLayerBtn);
    
    // 初始更新UI状态
    updateLayerUI();
}

2. 实现图层操作功能

// 更新图层UI状态
void MainWindow::updateLayerUI()
{
    // 保存当前选中的图层ID
    int currentId = -1;
    if (m_layerCombo->currentIndex() >= 0) {
        currentId = m_layerCombo->currentData().toInt();
    }
    
    // 清空并重新填充图层下拉框
    m_layerCombo->blockSignals(true);
    m_layerCombo->clear();
    
    QList layerIds = m_industrialView->layerIds();
    for (int id : layerIds) {
        QString name = m_industrialView->layerName(id);
        QIndustrialView::LayerType type = m_industrialView->layerType(id);
        
        QIcon icon;
        switch (type) {
            case QIndustrialView::ImageLayer: icon = QIcon(":/icons/image_layer.png"); break;
            case QIndustrialView::AnnotationLayer: icon = QIcon(":/icons/annotation_layer.png"); break;
            case QIndustrialView::MeasurementLayer: icon = QIcon(":/icons/measure_layer.png"); break;
            case QIndustrialView::TemporaryLayer: icon = QIcon(":/icons/temp_layer.png"); break;
        }
        
        m_layerCombo->addItem(icon, name, id);
    }
    
    // 恢复之前选中的图层
    int indexToSelect = m_layerCombo->findData(currentId);
    if (indexToSelect >= 0) {
        m_layerCombo->setCurrentIndex(indexToSelect);
    } else if (m_layerCombo->count() > 0) {
        m_layerCombo->setCurrentIndex(0);
    }
    m_layerCombo->blockSignals(false);
    
    // 更新图层属性控件状态
    bool hasLayers = m_layerCombo->count() > 0;
    bool hasSelection = m_layerCombo->currentIndex() >= 0;
    
    m_removeLayerBtn->setEnabled(hasSelection);
    m_renameLayerBtn->setEnabled(hasSelection);
    m_visibleCheck->setEnabled(hasSelection);
    m_opacitySlider->setEnabled(hasSelection);
    m_lockCheck->setEnabled(hasSelection);
    m_selectableCheck->setEnabled(hasSelection);
    m_raiseLayerBtn->setEnabled(hasSelection);
    m_lowerLayerBtn->setEnabled(hasSelection);
    m_raiseToTopBtn->setEnabled(hasSelection);
    m_lowerToBottomBtn->setEnabled(hasSelection);
    
    if (hasSelection) {
        int layerId = m_layerCombo->currentData().toInt();
        m_visibleCheck->setChecked(m_industrialView->isLayerVisible(layerId));
        m_opacitySlider->setValue(m_industrialView->layerOpacity(layerId) * 100);
        m_lockCheck->setChecked(m_industrialView->isLayerLocked(layerId));
        m_selectableCheck->setChecked(m_industrialView->isLayerSelectable(layerId));
    }
}

// 添加新图层
void MainWindow::onAddLayer()
{
    bool ok;
    QString name = QInputDialog::getText(this, tr("添加图层"), 
                                        tr("图层名称:"), QLineEdit::Normal, 
                                        tr("新图层"), &ok);
    if (ok && !name.isEmpty()) {
        // 默认添加标注层
        m_industrialView->addLayer(name, QIndustrialView::AnnotationLayer);
    }
}

// 删除图层
void MainWindow::onRemoveLayer()
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    if (QMessageBox::question(this, tr("删除图层"), 
                             tr("确定要删除图层 '%1' 吗?").arg(m_industrialView->layerName(layerId)),
                             QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
        m_industrialView->removeLayer(layerId);
    }
}

// 图层选择变化
void MainWindow::onLayerSelected(int index)
{
    if (index < 0) return;
    
    int layerId = m_layerCombo->itemData(index).toInt();
    m_visibleCheck->setChecked(m_industrialView->isLayerVisible(layerId));
    m_opacitySlider->setValue(m_industrialView->layerOpacity(layerId) * 100);
    m_lockCheck->setChecked(m_industrialView->isLayerLocked(layerId));
    m_selectableCheck->setChecked(m_industrialView->isLayerSelectable(layerId));
}

// 设置图层可见性
void MainWindow::onLayerVisibilityChanged(bool visible)
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    m_industrialView->setLayerVisible(layerId, visible);
}

// 设置图层不透明度
void MainWindow::onLayerOpacityChanged(int value)
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    m_industrialView->setLayerOpacity(layerId, value / 100.0);
}

// 设置图层锁定状态
void MainWindow::onLayerLockToggled(bool locked)
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    m_industrialView->setLayerLocked(layerId, locked);
}

// 设置图层可选状态
void MainWindow::onLayerSelectableToggled(bool selectable)
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    m_industrialView->setLayerSelectable(layerId, selectable);
}

// 上移一层
void MainWindow::onLayerRaise()
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    m_industrialView->raiseLayer(layerId);
}

// 下移一层
void MainWindow::onLayerLower()
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    m_industrialView->lowerLayer(layerId);
}

// 移到顶层
void MainWindow::onLayerRaiseToTop()
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    m_industrialView->raiseLayerToTop(layerId);
}

// 移到底层
void MainWindow::onLayerLowerToBottom()
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    m_industrialView->lowerLayerToBottom(layerId);
}

// 重命名图层
void MainWindow::onLayerRename()
{
    if (m_layerCombo->currentIndex() < 0) return;
    
    int layerId = m_layerCombo->currentData().toInt();
    QString oldName = m_industrialView->layerName(layerId);
    
    bool ok;
    QString newName = QInputDialog::getText(this, tr("重命名图层"), 
                                          tr("新名称:"), QLineEdit::Normal, 
                                          oldName, &ok);
    if (ok && !newName.isEmpty() && newName != oldName) {
        m_industrialView->renameLayer(layerId, newName);
    }
}

3. 添加菜单项和快捷键

// 在MainWindow构造函数中添加
void MainWindow::setupMenus()
{
    // ... 其他菜单项
    
    // 图层菜单
    QMenu* layerMenu = menuBar()->addMenu(tr("图层(&L)"));
    
    QAction* addLayerAct = new QAction(tr("添加图层"), this);
    addLayerAct->setShortcut(QKeySequence("Ctrl+Shift+N"));
    connect(addLayerAct, &QAction::triggered, this, &MainWindow::onAddLayer);
    layerMenu->addAction(addLayerAct);
    
    QAction* removeLayerAct = new QAction(tr("删除图层"), this);
    removeLayerAct->setShortcut(QKeySequence("Ctrl+Shift+D"));
    connect(removeLayerAct, &QAction::triggered, this, &MainWindow::onRemoveLayer);
    layerMenu->addAction(removeLayerAct);
    
    layerMenu->addSeparator();
    
    QAction* raiseLayerAct = new QAction(tr("上移一层"), this);
    raiseLayerAct->setShortcut(QKeySequence("Ctrl+]"));
    connect(raiseLayerAct, &QAction::triggered, this, &MainWindow::onLayerRaise);
    layerMenu->addAction(raiseLayerAct);
    
    QAction* lowerLayerAct = new QAction(tr("下移一层"), this);
    lowerLayerAct->setShortcut(QKeySequence("Ctrl+["));
    connect(lowerLayerAct, &QAction::triggered, this, &MainWindow::onLayerLower);
    layerMenu->addAction(lowerLayerAct);
    
    QAction* raiseToTopAct = new QAction(tr("移到顶层"), this);
    raiseToTopAct->setShortcut(QKeySequence("Ctrl+Shift+]"));
    connect(raiseToTopAct, &QAction::triggered, this, &MainWindow::onLayerRaiseToTop);
    layerMenu->addAction(raiseToTopAct);
    
    QAction* lowerToBottomAct = new QAction(tr("移到底层"), this);
    lowerToBottomAct->setShortcut(QKeySequence("Ctrl+Shift+["));
    connect(lowerToBottomAct, &QAction::triggered, this, &MainWindow::onLayerLowerToBottom);
    layerMenu->addAction(lowerToBottomAct);
    
    layerMenu->addSeparator();
    
    QAction* renameLayerAct = new QAction(tr("重命名图层"), this);
    renameLayerAct->setShortcut(QKeySequence("F2"));
    connect(renameLayerAct, &QAction::triggered, this, &MainWindow::onLayerRename);
    layerMenu->addAction(renameLayerAct);
}

4. 添加右键上下文菜单

// 在MainWindow中添加
void MainWindow::contextMenuEvent(QContextMenuEvent* event)
{
    QMenu menu(this);
    
    // 添加通用操作...
    
    // 添加图层相关操作
    if (m_industrialView->layerCount() > 0) {
        menu.addSeparator();
        
        QMenu* layerMenu = menu.addMenu(tr("图层"));
        
        QAction* addLayerAct = layerMenu->addAction(tr("添加图层"));
        connect(addLayerAct, &QAction::triggered, this, &MainWindow::onAddLayer);
        
        if (m_layerCombo->currentIndex() >= 0) {
            QAction* removeLayerAct = layerMenu->addAction(tr("删除当前图层"));
            connect(removeLayerAct, &QAction::triggered, this, &MainWindow::onRemoveLayer);
            
            QAction* renameLayerAct = layerMenu->addAction(tr("重命名当前图层"));
            connect(renameLayerAct, &QAction::triggered, this, &MainWindow::onLayerRename);
            
            layerMenu->addSeparator();
            
            QAction* raiseLayerAct = layerMenu->addAction(tr("上移一层"));
            connect(raiseLayerAct, &QAction::triggered, this, &MainWindow::onLayerRaise);
            
            QAction* lowerLayerAct = layerMenu->addAction(tr("下移一层"));
            connect(lowerLayerAct, &QAction::triggered, this, &MainWindow::onLayerLower);
            
            QAction* raiseToTopAct = layerMenu->addAction(tr("移到顶层"));
            connect(raiseToTopAct, &QAction::triggered, this, &MainWindow::onLayerRaiseToTop);
            
            QAction* lowerToBottomAct = layerMenu->addAction(tr("移到底层"));
            connect(lowerToBottomAct, &QAction::triggered, this, &MainWindow::onLayerLowerToBottom);
        }
    }
    
    menu.exec(event->globalPos());
}

5. 添加状态栏信息

// 在MainWindow中添加
void MainWindow::updateStatusBar()
{
    // ... 其他状态信息
    
    // 显示当前图层信息
    if (m_layerCombo->currentIndex() >= 0) {
        int layerId = m_layerCombo->currentData().toInt();
        QString layerInfo = tr("图层: %1 [%2]")
                           .arg(m_industrialView->layerName(layerId))
                           .arg(m_industrialView->layerType(layerId) == QIndustrialView::ImageLayer ? 
                               tr("图像层") : tr("标注层"));
        statusBar()->showMessage(layerInfo);
    } else {
        statusBar()->showMessage(tr("无活动图层"));
    }
}

通过以上实现,我们在MainWindow中集成了QIndustrialView的图层管理功能,包括:

  1. 图层工具栏 - 提供快速访问常用图层操作

  2. 图层菜单 - 提供完整的图层操作命令

  3. 右键上下文菜单 - 方便快捷操作

  4. 状态栏信息 - 显示当前图层状态

  5. 快捷键支持 - 提高操作效率

所有图层操作都会实时更新UI状态,并通过信号槽机制与QIndustrialView保持同步。用户可以通过多种方式管理图层,包括创建、删除、重命名、调整顺序和修改属性等。

你可能感兴趣的:(QT开发,qt,图像显示控件,图层管理)