.h文件
protected:
void saveAxisRange();
void wheelEvent(QWheelEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
private:
QPoint m_lastPoint;
bool m_isPress = false; //这里我把平移的判定初始化成了false,解决鼠标一移进QchartView就跟随移动的情况
bool m_ctrlPress;
bool m_alreadySaveRange;
double m_xMin, m_xMax, m_yMin, m_yMax;
QGraphicsSimpleTextItem* m_coordItem;
// 框选
bool m_isSelecting = false; // 是否正在框选
QPoint m_selectionStart; // 框选起点
QGraphicsRectItem* m_selectionRect = nullptr; // 选框图形项
.cpp文件
void saveAxisRange()
{
QValueAxis *axisX = dynamic_cast<QValueAxis*>(this->chart()->axisX());
m_xMin = axisX->min();
m_xMax = axisX->max();
QValueAxis *axisY = dynamic_cast<QValueAxis*>(this->chart()->axisY());
m_yMin = axisY->min();
m_yMax = axisY->max();
}
void wheelEvent(QWheelEvent *event)
{
获取当前轴的缩放因子(0.9为缩小,1.1为放大)
//const double zoomFactor = 0.9;
//const double minRange = 0.01; // 防止缩放到负数或过小
获取当前轴范围
//QValueAxis* axisX = qobject_cast<QValueAxis*>(chart()->axes(Qt::Horizontal).first());
//QValueAxis* axisY = qobject_cast<QValueAxis*>(chart()->axes(Qt::Vertical).first());
//if(!axisX || !axisY)
//{
// return;
//}
计算缩放方向(向上滚为缩小,向下滚为放大)
//double delta = event->angleDelta().y() > 0 ? zoomFactor : 1.0 / zoomFactor;
根据修饰键选择缩放轴
//if(event->modifiers() & Qt::ControlModifier)
//{
// // 缩放Y轴
// double newMinY = axisY->min() * delta;
// double newMaxY = axisY->max() * delta;
// if(newMaxY - newMinY > minRange)
// {
// axisY->setRange(newMinY, newMaxY);
// }
//}
//else
//{
// // 缩放X轴
// double newMinX = axisX->min() * delta;
// double newMaxX = axisX->max() * delta;
// if(newMaxX - newMinX > minRange)
// {
// axisX->setRange(newMinX, newMaxX);
// }
//}
//event->accept();
const QPoint curPos = event->pos();
QPointF curVal = this->chart()->mapToValue(QPointF(curPos));
if(!m_alreadySaveRange)
{
this->saveAxisRange();
m_alreadySaveRange = true;
}
const double factor = 1.5;//缩放比例
if(event->modifiers() & Qt::ControlModifier)
{
//Y轴
QValueAxis *axisY = dynamic_cast<QValueAxis*>(this->chart()->axisY());
const double yMin = axisY->min();
const double yMax = axisY->max();
const double yCentral = curVal.y();
double bottomOffset;
double topOffset;
if(event->delta() > 0)
{
//放大
bottomOffset = 1.0 / factor * (yCentral - yMin);
topOffset = 1.0 / factor * (yMax - yCentral);
}
else
{
//缩小
bottomOffset = 1.0 * factor * (yCentral - yMin);
topOffset = 1.0 * factor * (yMax - yCentral);
}
this->chart()->axisY()->setRange(yCentral - bottomOffset, yCentral + topOffset);
}
else
{
//X轴
QValueAxis *axisX = dynamic_cast<QValueAxis*>(this->chart()->axisX());
const double xMin = axisX->min();
const double xMax = axisX->max();
const double xCentral = curVal.x();
double leftOffset;
double rightOffset;
if(event->delta() > 0)
{
//放大
leftOffset = 1.0 / factor * (xCentral - xMin);
rightOffset = 1.0 / factor * (xMax - xCentral);
}
else
{
//缩小
leftOffset = 1.0 * factor * (xCentral - xMin);
rightOffset = 1.0 * factor * (xMax - xCentral);
}
this->chart()->axisX()->setRange(xCentral - leftOffset, xCentral + rightOffset);
}
}
void mousePressEvent(QMouseEvent *event)
{
//if(event->button() == Qt::LeftButton)
//{
// m_lastPoint = event->pos();
// m_isPress = true;
//}
if(event->button() == Qt::LeftButton)
{
// 检测 Ctrl 键是否按下
if(QApplication::keyboardModifiers() & Qt::ControlModifier)
{
// 开始框选
m_isSelecting = true;
m_selectionStart = event->pos();
// 创建选框图形项
if(!m_selectionRect)
{
m_selectionRect = new QGraphicsRectItem();
m_selectionRect->setPen(QPen(Qt::blue, 1, Qt::DashLine));
m_selectionRect->setBrush(QColor(100, 100, 255, 50));
chart()->scene()->addItem(m_selectionRect);
}
}
else
{
// 正常平移模式
m_lastPoint = event->pos();
m_isPress = true;
}
}
}
void mouseMoveEvent(QMouseEvent *event)
{
/*if(!m_coordItem)
{
m_coordItem = new QGraphicsSimpleTextItem(this->chart());
m_coordItem->setZValue(5);
m_coordItem->setPos(100, 60);
m_coordItem->show();
}
const QPoint curPos = event->pos();
if(m_isPress)
{
QPoint offset = curPos - m_lastPoint;
m_lastPoint = curPos;
if(!m_alreadySaveRange)
{
this->saveAxisRange();
m_alreadySaveRange = true;
}
this->chart()->scroll(-offset.x(), offset.y());
}*/
// 更新坐标显示(原功能保留)
if(!m_coordItem)
{
m_coordItem = new QGraphicsSimpleTextItem(chart());
m_coordItem->setZValue(5);
m_coordItem->setPos(100, 60);
}
// 处理框选逻辑
if(m_isSelecting)
{
// 更新选框图形
QRectF rect(m_selectionStart, event->pos());
m_selectionRect->setRect(rect.normalized());
}
// 处理平移逻辑
else if(m_isPress)
{
QPoint offset = event->pos() - m_lastPoint;
m_lastPoint = event->pos();
if(!m_alreadySaveRange)
{
saveAxisRange();
m_alreadySaveRange = true;
}
chart()->scroll(-offset.x(), offset.y());
}
}
void mouseReleaseEvent(QMouseEvent *event)
{
//m_isPress = false;
//if(event->button() == Qt::RightButton)
//{
// if(m_alreadySaveRange)
// {
// this->chart()->axisX()->setRange(m_xMin, m_xMax);
// this->chart()->axisY()->setRange(m_yMin, m_yMax);
// }
//}
if(event->button() == Qt::LeftButton)
{
if(m_isSelecting)
{
// 应用框选缩放
QRectF rect = m_selectionRect->rect();
QPointF topLeft = chart()->mapToValue(rect.topLeft());
QPointF bottomRight = chart()->mapToValue(rect.bottomRight());
chart()->axisX()->setRange(topLeft.x(), bottomRight.x());
chart()->axisY()->setRange(bottomRight.y(), topLeft.y()); // Y轴方向反转
// 清理选框
chart()->scene()->removeItem(m_selectionRect);
delete m_selectionRect;
m_selectionRect = nullptr;
m_isSelecting = false;
}
else
{
m_isPress = false;
}
}
// 原右键恢复功能保留
else if(event->button() == Qt::RightButton)
{
if(m_alreadySaveRange)
{
chart()->axisX()->setRange(m_xMin, m_xMax);
chart()->axisY()->setRange(m_yMin, m_yMax);
}
}
}
构造函数中添加代码:
grabGesture(Qt::PinchGesture); //这里只grabGesture了PinchGesture