图例QCPLegend
一、QCPLegend 概述
QCPLegend 是 QCustomPlot 中负责管理图表图例的类,用于显示图表中各元素的标识和说明。
二、功能
-
自动/手动管理图例项
-
支持多行列布局
-
可自定义外观和交互
-
支持拖拽和选择
1. 核心属性
属性 | 类型 | 说明 |
---|---|---|
borderPen | QPen | 图例边框的画笔样式 |
brush | QBrush | 图例背景的画刷样式 |
font | QFont | 图例文本的字体 |
textColor | QColor | 图例文本颜色 |
iconSize | QSize | 图例项图标尺寸(默认20x16) |
iconTextPadding | int | 图标和文本之间的间距(默认4像素) |
iconBorderPen | QPen | 图例项图标边框的画笔 |
selectableParts | SelectablePart | 可选中部分(枚举组合) |
selectedParts | SelectablePart | 当前选中部分 |
selectedBorderPen | QPen | 选中状态的边框画笔 |
selectedBrush | QBrush | 选中状态的背景画刷 |
selectedFont | QFont | 选中状态的文本字体 |
selectedTextColor | QColor | 选中状态的文本颜色 |
2. 主要方法
2.1 布局与外观
方法 | 参数 | 返回值 | 说明 |
---|---|---|---|
setVisible | bool on | void | 显示/隐藏图例 |
setFillOrder | FillOrder order | void | 设置图例项排列顺序 |
setRowSpacing | int spacing | void | 设置行间距 |
setColumnSpacing | int spacing | void | 设置列间距 |
setWrap | int count | void | 设置每行/列最大项数 |
2.2 图例项操作
方法 | 参数 | 返回值 | 说明 |
---|---|---|---|
addItem | QCPAbstractPlottable *plottable | QCPPlottableLegendItem* | 添加绘图项到图例 |
item | int index | QCPAbstractLegendItem* | 获取指定索引的图例项 |
itemWithPlottable | QCPAbstractPlottable *plottable | QCPPlottableLegendItem* | 获取关联特定绘图项的图例项 |
itemCount | - | int | 获取图例项数量 |
clearItems | - | void | 清除所有图例项 |
2.3 选择与交互
方法 | 参数 | 返回值 | 说明 |
---|---|---|---|
selectTest | const QPointF &pos, bool onlySelectable | double | 测试点击位置是否在图例上 |
setSelectable | SelectablePart parts | void | 设置可选部分 |
setSelected | SelectablePart parts | void | 设置选中状态 |
3. 信号列表
信号 | 参数 | 说明 |
---|---|---|
selectionChanged | QCPLegend::SelectablePart parts | 选中状态改变时触发 |
selectableChanged | QCPLegend::SelectablePart parts | 可选状态改变时触发 |
4. 枚举类型
QCPLegend::SelectablePart
值 | 说明 |
---|---|
spNone | 不可选 |
spLegendBox | 图例框可选 |
spItems | 图例项可选 |
spAll | 全部可选 |
QCPLegend::FillOrder
值 | 说明 |
---|---|
foRowsFirst | 先填充行(默认) |
foColumnsFirst | 先填充列 |
5. 基本使用示例
cpp
// 创建图例并添加到图表
QCPLegend *legend = new QCPLegend();
customPlot->plotLayout()->addElement(1, 0, legend); // 添加到底部// 设置图例样式
legend->setBorderPen(QPen(Qt::black, 1));
legend->setBrush(QBrush(Qt::white));
legend->setFont(QFont("Arial", 9));// 添加曲线到图例
QCPGraph *graph = customPlot->addGraph();
graph->setName("温度曲线");
legend->addItem(new QCPPlottableLegendItem(legend, graph));// 启用交互选择
legend->setSelectableParts(QCPLegend::spItems);
legend->setSelectedParts(QCPLegend::spNone);// 连接选择信号
connect(legend, &QCPLegend::selectionChanged, [](QCPLegend::SelectablePart parts){qDebug() << "图例选中部分:" << parts;
});
三、基本使用方法
1. 添加图例到图表
cpp
// 添加默认图例(通常已在构造函数中自动添加)
customPlot->legend->setVisible(true);// 设置图例位置
customPlot->legend->setBrush(QBrush(QColor(255,255,255,200))); // 半透明背景
customPlot->legend->setBorderPen(QPen(Qt::darkGray));
customPlot->layout()->insertRow(0); // 在上方添加空行
customPlot->legend->setFillOrder(QCPLegend::foColumnsFirst); // 填充顺序
customPlot->plotLayout()->addElement(0, 0, customPlot->legend); // 添加到布局
customPlot->plotLayout()->setMargins(QMargins(5,5,5,5)); // 设置边距
2. 添加图例项
cpp
// 自动添加图形图例
QCPGraph *graph = customPlot->addGraph();
graph->setName("正弦曲线"); // 设置名称即自动添加到图例// 手动添加自定义图例项
QCPPlottableLegendItem *legendItem = new QCPPlottableLegendItem(customPlot->legend, customPlot->graph(0));
legendItem->setText("自定义标签");// 添加纯文本图例项
QCPLegendText *textItem = new QCPLegendText(customPlot->legend);
textItem->setText("参考线");
textItem->setFont(QFont("Arial", 9));
customPlot->legend->addItem(textItem);
四、布局与样式配置
1. 行列设置
cpp
// 设置图例行数
customPlot->legend->setRowCount(2);// 设置图列数
customPlot->legend->setColumnCount(3);// 设置填充顺序(先行后列/先列后行)
customPlot->legend->setFillOrder(QCPLegend::foRowsFirst);// 设置自动换行
customPlot->legend->setWrap(4); // 每行最多4个项
2. 外观样式
cpp
// 设置图例边框
customPlot->legend->setBorderPen(QPen(Qt::black, 1));// 设置背景
customPlot->legend->setBrush(QBrush(QColor(255,255,255,230)));// 设置文本颜色
customPlot->legend->setTextColor(Qt::darkBlue);// 设置图标大小
customPlot->legend->setIconSize(20, 10);// 设置项间距
customPlot->legend->setItemSpacing(3); // 项间水平间距
customPlot->legend->setIconTextPadding(8); // 图标与文本间距
五、交互功能
1. 选择与拖拽
cpp
// 启用选择
customPlot->legend->setSelectableParts(QCPLegend::spItems); // 可选择项
customPlot->legend->setSelectedParts(QCPLegend::spNone); // 初始无选中// 启用拖拽
customPlot->legend->setDraggable(true);// 选择事件处理
connect(customPlot, &QCustomPlot::legendClick, [](QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event){qDebug() << "点击了图例项:" << item->text();
});// 双击事件处理
connect(customPlot, &QCPLegend::doubleClick, [](QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event){if (item) {if (auto plottableItem = dynamic_cast<QCPPlottableLegendItem*>(item)) {plottableItem->plottable()->setVisible(!plottableItem->plottable()->visible());customPlot->replot();}}
});
2. 自定义上下文菜单
cpp
// 启用上下文菜单
customPlot->setContextMenuPolicy(Qt::CustomContextMenu);connect(customPlot, &QCustomPlot::customContextMenuRequested, [=](const QPoint &pos){if (customPlot->legend->selectTest(pos, false) >= 0) {QMenu menu(customPlot);menu.addAction("隐藏图例", [=](){ customPlot->legend->setVisible(false); });menu.addAction("导出图例", [=](){ exportLegend(); });menu.exec(customPlot->mapToGlobal(pos));}
});
六、高级管理技巧
1. 分组管理
cpp
// 创建分组图例
QCPLegend *subLegend = new QCPLegend();
customPlot->plotLayout()->addElement(1, 1, subLegend); // 添加到特定位置// 将特定图形分配到子图例
QCPGraph *specialGraph = customPlot->addGraph();
specialGraph->setName("特殊曲线");
specialGraph->addToLegend(subLegend);
2. 动态更新
cpp
// 动态更新图例文本
connect(customPlot->graph(0), &QCPGraph::nameChanged, [=](const QString &newName){customPlot->legend->itemWithPlottable(customPlot->graph(0))->setText(newName + " (动态)");
});// 根据数据范围更新图例
void updateLegendWithStats(QCPGraph *graph) {bool ok;QCPRange range = graph->data()->valueRange(ok);if (ok) {graph->setName(QString("均值: %1").arg((range.lower+range.upper)/2, 0, 'f', 2));}
}
3. 自定义绘制
cpp
// 自定义图例项
class CustomLegendItem : public QCPAbstractLegendItem {
public:// 必须实现的纯虚函数virtual void draw(QCPPainter *painter) override {// 自定义绘制逻辑}virtual QSize minimumSizeHint() const override {// 返回最小尺寸}
};// 使用自定义图例项
CustomLegendItem *customItem = new CustomLegendItem(customPlot->legend);
customPlot->legend->addItem(customItem);
七、性能优化
1、限制图例项数量:
cpp
// 只显示前5个图例项
for (int i=5; i<customPlot->legend->itemCount(); ++i) {customPlot->legend->itemAt(i)->setVisible(false);
}
2、简化图例样式:
cpp
customPlot->legend->setAntialiased(false); // 关闭抗锯齿
3、批量操作:
cpp
customPlot->legend->setVisible(false); // 先隐藏
// ...大量图例更新操作...
customPlot->legend->setVisible(true); // 最后显示
八、实用代码片段
1. 导出图例为图片
cpp
void exportLegendToImage(const QString &filename, QCPLegend *legend) {QPixmap pixmap(legend->outerRect().size().toSize());QCPPainter painter(&pixmap);legend->draw(&painter);pixmap.save(filename);
}
2. 查找特定图例项
cpp
// 通过名称查找图例项
QCPAbstractLegendItem* findLegendItem(const QString &name) {for (int i=0; i<customPlot->legend->itemCount(); ++i) {if (customPlot->legend->itemAt(i)->text() == name)return customPlot->legend->itemAt(i);}return nullptr;
}
3. 同步图例与图形可见性
cpp
// 当图形可见性改变时更新图例
connect(customPlot, &QCustomPlot::plottableVisibilityChanged, [=](QCPAbstractPlottable *plottable){if (auto item = customPlot->legend->itemWithPlottable(plottable)) {item->setTextColor(plottable->visible() ? Qt::black : Qt::gray);}
});
通过合理使用 QCPLegend,您可以创建出既美观又功能强大的图表图例系统,有效提升数据可视化的专业性和交互性。