What a code!
要在前后两个图表之间连接对应的坐标轴刻度点,可以通过在父部件中绘制线条来实现。以下是具体步骤和代码实现:
步骤说明
- 重写paintEvent函数:在
Bigraph
的paintEvent
中绘制连接线。 - 获取刻度值列表:根据每个坐标轴的最小值、最大值和刻度数量生成刻度值。
- 转换坐标位置:将刻度值转换为在各自图表中的位置,再转换为父部件中的全局坐标。
- 绘制连接线:使用QPainter在对应的刻度点之间绘制线条。
代码实现
在Bigraph.h
中添加以下内容:
#include <QPainter>
protected:
void paintEvent(QPaintEvent *event) override;
private:
void connectAxisTicks(QPainter *painter, QChart *backChart, QLineSeries *backSeries,
QChart *fontChart, QLineSeries *fontSeries, bool isXAxis);
QList<qreal> getTickValues(QValueAxis *axis);
在Bigraph.cpp
中添加以下实现:
void Bigraph::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(QColor(Qt::gray), 1, Qt::DotLine));
// 连接X轴和Y轴的刻度线
connectAxisTicks(&painter, backChart, backSeries, fontChart, fontSeries, true); // X轴
connectAxisTicks(&painter, backChart, backSeries, fontChart, fontSeries, false); // Y轴
}
void Bigraph::connectAxisTicks(QPainter *painter, QChart *backChart, QLineSeries *backSeries,
QChart *fontChart, QLineSeries *fontSeries, bool isXAxis)
{
// 获取前后图表的坐标轴
QValueAxis *backAxis = isXAxis ? qobject_cast<QValueAxis*>(backChart->axes(Qt::Horizontal).first()
: qobject_cast<QValueAxis*>(backChart->axes(Qt::Vertical).first());
QValueAxis *fontAxis = isXAxis ? qobject_cast<QValueAxis*>(fontChart->axes(Qt::Horizontal).first()
: qobject_cast<QValueAxis*>(fontChart->axes(Qt::Vertical).first());
if (!backAxis || !fontAxis) return;
// 获取刻度值列表
QList<qreal> backTicks = getTickValues(backAxis);
QList<qreal> fontTicks = getTickValues(fontAxis);
int minCount = qMin(backTicks.size(), fontTicks.size());
for (int i = 0; i < minCount; ++i) {
// 转换backChart中的刻度点到全局坐标
QPointF backPoint;
if (isXAxis) {
backPoint = backChart->mapToPosition(QPointF(backTicks[i], backAxis->min()), backSeries);
} else {
backPoint = backChart->mapToPosition(QPointF(backAxis->min(), backTicks[i]), backSeries);
}
QPoint backViewPos = backChartView->mapFromScene(backPoint);
QPoint backGlobalPos = backChartView->pos() + backViewPos;
// 转换fontChart中的刻度点到全局坐标
QPointF fontPoint;
if (isXAxis) {
fontPoint = fontChart->mapToPosition(QPointF(fontTicks[i], fontAxis->min()), fontSeries);
} else {
fontPoint = fontChart->mapToPosition(QPointF(fontAxis->min(), fontTicks[i]), fontSeries);
}
QPoint fontViewPos = fontChartView->mapFromScene(fontPoint);
QPoint fontGlobalPos = fontChartView->pos() + fontViewPos;
// 绘制连接线
painter->drawLine(backGlobalPos, fontGlobalPos);
}
}
QList<qreal> Bigraph::getTickValues(QValueAxis *axis)
{
QList<qreal> ticks;
qreal min = axis->min();
qreal max = axis->max();
int tickCount = axis->tickCount();
if (tickCount < 2) return ticks;
qreal step = (max - min) / (tickCount - 1);
for (int i = 0; i < tickCount; ++i) {
ticks.append(min + i * step);
}
return ticks;
}
说明
- 坐标转换:使用
QChart::mapToPosition
将刻度值转换为图表内的坐标,再通过QChartView::mapFromScene
转换为视图坐标,最后加上视图在父部件中的位置得到全局坐标。 - 刻度生成:根据轴的
min
、max
和tickCount
生成均匀分布的刻度值。 - 线条绘制:使用灰色虚线连接对应的刻度点,形成立体效果。
确保两个图表的坐标轴范围和刻度数一致,以保证连接线正确对齐。通过调整QPen
的参数可以更改线条样式。