热度 5
2023-11-17 15:39
1799 次阅读|
0 个评论
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 = 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 ); // min() + deltaYValue, 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 ++; } 测试一下: