QGraphicsView 本身并没有鼠标操作功能。需要另写函数实现。基本的思路是写一个新的类,继承QGraphicsView,
class ChartView : public QChartView
再重载鼠标操作函数。
void mousePressEvent(QMouseEvent *event) override
void mouseMoveEvent(QMouseEvent *event) override
void mouseReleaseEvent(QMouseEvent *event) override
void wheelEvent(QWheelEvent *event) override
需要使用3个私有的变量记录鼠标的动作状态
private:
bool isClicking; //记录鼠标左键按下和释放,只有在按下鼠标再拖动时才产生动作。
int startX; // 记录鼠标按下时起始点位置
int startY;
使用两个公共指针,指向序列数据和折线图
public:
QLineSeries *series; // 用于折线图的数据序列
QChart *chart; // 图指针
在鼠标左键按下的事件处理函数中使 isClicking 为 true,同时使用StartX StartY 记录起始点位置
在鼠标左键释放的事件处理函数中使用isClicking 为 false
在鼠标移动事件中,获取移动的距离,改变数轴的范围。这样就可以实现鼠标点击拖动。
在鼠标滚轮滚动的事件中,获取滚轮滚动量和方向,同步改变数轴的范围,实现图片左右移动。
生成一个 chartview.h 文件,并添加到工程中。
#ifndef CHARTVIEW_H
#define CHARTVIEW_H
#include <QApplication>
#include <QtCharts>
#include <QLineSeries>
#include <QChart>
#include <QChartView>
#include <QValueAxis>
#include <QMouseEvent>
QT_CHARTS_USE_NAMESPACE
class ChartView : public QChartView
{
public:
QLineSeries *series;
QChart *chart;
ChartView(QWidget *parent = nullptr) : QChartView(parent), isClicking(false)
{
// 创建折线图
series = new QLineSeries();
series->append(-3, 4);
series->append(-2, 3);
series->append(-1, 2);
series->append(0, 1);
series->append(1, 3);
series->append(2, 2);
series->append(3, 4);
chart = new QChart();
chart->addSeries(series);
chart->createDefaultAxes();
chart->legend()->hide();
setChart(chart);
setRenderHint(QPainter::Antialiasing);
setRubberBand(QChartView::RectangleRubberBand);
}
protected:
void mousePressEvent(QMouseEvent *event) override
{
if (event->button() == Qt::LeftButton)
{
isClicking = true;
startX = event->x();
startY = event->y();
}
}
void mouseMoveEvent(QMouseEvent *event) override
{
if (isClicking)
{
int deltaX = event->x() - startX;
int deltaY = event->y() - startY;
// QChart *chart = this->chart();
if (event->modifiers() == Qt::ControlModifier)
{
QValueAxis *axisX = qobject_cast<QValueAxis *>(chart->axes(Qt::Horizontal).at(0));
QValueAxis *axisY = qobject_cast<QValueAxis *>(chart->axes(Qt::Vertical).at(0));
if (axisX && axisY)
{
qreal deltaXRatio = deltaX / chart->plotArea().width();
qreal deltaYRatio = deltaY / chart->plotArea().height();
qreal deltaXValue = deltaXRatio * (axisX->max() - axisX->min());
qreal deltaYValue = deltaYRatio * (axisY->max() - axisY->min());
axisX->setRange(axisX->min() - deltaXValue, axisX->max() - deltaXValue);
// axisY->setRange(axisY->min() + deltaYValue, axisY->max() + deltaYValue);
}
}
else
{
chart->scroll(-deltaX, deltaY);
}
startX = event->x();
startY = event->y();
}
}
void mouseReleaseEvent(QMouseEvent *event) override
{
if (event->button() == Qt::LeftButton)
{
isClicking = false;
}
}
void virtual wheelEvent(QWheelEvent *event) override{
qreal temp = event->angleDelta().y();
QValueAxis *axisX = qobject_cast<QValueAxis *>(chart->axes(Qt::Horizontal).at(0));
if(temp>0)
axisX->setRange(axisX->min() + 1 , axisX->max() + 1);
else
axisX->setRange(axisX->min() - 1 , axisX->max() - 1);
}
private:
bool isClicking;
int startX;
int startY;
};
#endif // CHARTVIEW_H
在窗口中增加一个Graphics view 控制,并提升为这个扩展的类。
现在这个折线图就可以使用鼠标操作了。
因为这个类中有公有的 QLineSeries 指针,在获取指针后可以对数据序列进行操作。
void MainWindow::on_pushButton_clicked()
{
static int i = 7;
QLineSeries *p;
p = ui->graphicsView->series; // 获取数据序列指针
p->append(i,3);
i++;
}
测试一下:
作者: southcreek, 来源:面包板社区
链接: https://mbb.eet-china.com/blog/uid-me-408807.html
版权声明:本文为博主原创,未经本人允许,禁止转载!
文章评论(0条评论)
登录后参与讨论