当前位置:   article > 正文

Qt篇——QChartView实现鼠标滚轮缩放、鼠标拖拽平移、鼠标双击重置缩放平移、曲线点击显示坐标_qt chart图表移动缩放返回原点

qt chart图表移动缩放返回原点

话不多说。

 效果:(动图依次展示:①点击曲线显示坐标->②平移->③缩放->④双击还原)

第一步:自定义QChartView,直接搬

FirtCurveChartView.h

  1. #ifndef FITCURVECHARTVIEW_H
  2. #define FITCURVECHARTVIEW_H
  3. #include <QtCharts>
  4. class FitCurveChartView : public QChartView {
  5. Q_OBJECT
  6. public:
  7. FitCurveChartView(QWidget *parent = Q_NULLPTR);
  8. ~FitCurveChartView();
  9. protected:
  10. void mousePressEvent(QMouseEvent *event);
  11. void mouseMoveEvent(QMouseEvent *event);
  12. void mouseReleaseEvent(QMouseEvent *event);
  13. void mouseDoubleClickEvent(QMouseEvent *event);
  14. void wheelEvent(QWheelEvent *event);
  15. signals:
  16. void signalMouseEvent(int eventId, QMouseEvent *event);
  17. void signalWheelEvent(QWheelEvent *event);
  18. };
  19. #endif // FITCURVECHARTVIEW_H

FirtCurveChartView.cpp

  1. #include "FitCurveChartView.h"
  2. FitCurveChartView::FitCurveChartView(QWidget *parent) {
  3. }
  4. FitCurveChartView::~FitCurveChartView() {
  5. }
  6. void FitCurveChartView::mousePressEvent(QMouseEvent *event) {
  7. emit signalMouseEvent(0, event);
  8. QChartView::mousePressEvent(event);
  9. }
  10. void FitCurveChartView::mouseMoveEvent(QMouseEvent *event) {
  11. emit signalMouseEvent(1, event);
  12. QChartView::mouseMoveEvent(event);
  13. }
  14. void FitCurveChartView::mouseReleaseEvent(QMouseEvent *event) {
  15. emit signalMouseEvent(2, event);
  16. QChartView::mouseReleaseEvent(event);
  17. }
  18. void FitCurveChartView::mouseDoubleClickEvent(QMouseEvent *event) {
  19. emit signalMouseEvent(3, event);
  20. QChartView::mouseDoubleClickEvent(event);
  21. }
  22. void FitCurveChartView::wheelEvent(QWheelEvent *event) {
  23. emit signalWheelEvent(event);
  24. QChartView::wheelEvent(event);
  25. }

第二步:在主界面代码中使用,我的是在自定义对话框里面,你们可以直接在窗口中使用

举例:fitcurvedialog.h

  1. #ifndef FITCURVEDIALOG_H
  2. #define FITCURVEDIALOG_H
  3. #include <QDialog>
  4. #include "FitCurveChartView.h"
  5. namespace Ui {
  6. class FitCurveDialog;
  7. }
  8. class FitCurveDialog : public QDialog
  9. {
  10. Q_OBJECT
  11. public:
  12. explicit FitCurveDialog(QWidget *parent = nullptr);
  13. ~FitCurveDialog();
  14. void initQChartView();
  15. void updateXYGuideLine();
  16. void resetZoomAndScroll();
  17. QVector<int> getAxisRanges();
  18. public slots:
  19. void theSlotMouseEvent(int eventId, QMouseEvent *event);
  20. void theSlotWheelEvent(QWheelEvent *event);
  21. private:
  22. Ui::FitCurveDialog *ui;
  23. FitCurveChartView *curveChartView;
  24. QChart *curveChart;
  25. QSplineSeries* fitPointsSeriesS; //要显示的曲线原始数据
  26. QScatterSeries* tipSeries;
  27. QSplineSeries* xGuideSeries; //鼠标悬浮位置点的x轴辅助线
  28. QSplineSeries* yGuideSeries; //鼠标悬浮位置点的y轴辅助线
  29. bool isPressed = false; //图标是否在拖拽中
  30. QPoint pressedPoint; //鼠标拖拽起点
  31. };
  32. #endif // FITCURVEDIALOG_H

fitcurvedialog.cpp    (UI文件里面就放了一个水平布局chartLayout)

  1. #include "fitcurvedialog.h"
  2. #include "ui_fitcurvedialog.h"
  3. FitCurveDialog::FitCurveDialog(QWidget *parent) :
  4. QDialog(parent),
  5. ui(new Ui::FitCurveDialog)
  6. {
  7. ui->setupUi(this);
  8. qApp->setOverrideCursor(Qt::ArrowCursor); //允许系统弹窗、提示
  9. initQChartView();
  10. }
  11. void FitCurveDialog::initQChartView() {
  12. //创建图表框架
  13. curveChartView = new FitCurveChartView(this);
  14. curveChartView->setMaximumWidth(1730);
  15. curveChartView->setMinimumHeight(480);
  16. curveChart = new QChart();
  17. curveChart->setTheme(QChart::ChartThemeBlueIcy);
  18. curveChart->setContentsMargins(0, 0, 0, 0); //设置外边界全部为0, 根据自己实际情况设置
  19. curveChart->setMargins(QMargins(5, -30, 5, 10)); //设置内边界, 根据自己实际情况设置
  20. curveChart->setBackgroundRoundness(0); //设置表格边框圆角半径
  21. curveChartView->setChart(curveChart);
  22. //创建折线序列
  23. fitPointsSeriesS = new QSplineSeries(this); //原始数据曲线
  24. fitPointsSeriesS->setUseOpenGL(true);
  25. xGuideSeries = new QSplineSeries(this);
  26. yGuideSeries = new QSplineSeries(this);
  27. tipSeries = new QScatterSeries(); // 创建一个散点数据集对象,用于显示
  28. tipSeries->setMarkerShape(QScatterSeries::MarkerShapeCircle); // 设置绘制的散点的样式为圆
  29. tipSeries->setMarkerSize(10);
  30. QObject::connect(fitPointsSeriesS, &QSplineSeries::clicked, [=](const QPointF &point)mutable{
  31. QPointF tempPoint;
  32. QVector<QPointF> tempList(fitPointsSeriesS->pointsVector()); //复制曲线中的数据进行计算, 因为直接使用会导致卡顿
  33. int tempX = qRound(point.x());
  34. int tempY = -999;
  35. for (int i = 0; i < tempList.size(); i++) {
  36. if (tempList[i].x() == tempX) {
  37. tempY = tempList[i].y();
  38. tempPoint.setX(tempX);
  39. tempPoint.setY(tempY);
  40. break;
  41. }
  42. }
  43. if (tempY != -999) {
  44. QToolTip::showText(QCursor::pos(), QString("(%1,%2)").arg(tempX).arg(tempY));
  45. QVector<QPointF> tipList;
  46. tipList.append(tempPoint);
  47. tipSeries->replace(tipList);
  48. updateXYGuideLine();
  49. }
  50. });
  51. curveChart->addSeries(xGuideSeries);
  52. curveChart->addSeries(yGuideSeries);
  53. curveChart->addSeries(fitPointsSeriesS);
  54. curveChart->addSeries(tipSeries);
  55. //添加数据绘制
  56. size_t count = 20000;
  57. QVector<QPointF> list;
  58. for (size_t i = 0; i < count; i++) {
  59. list.append(QPoint(i, int(i / 40)));
  60. }
  61. fitPointsSeriesS->replace(list);
  62. //创建坐标轴
  63. QValueAxis* axisX = new QValueAxis;
  64. axisX->setRange(0, 20000);
  65. axisX->setTickCount(21);
  66. axisX->setLabelFormat("%d");
  67. axisX->setLabelsAngle(-90); //坐标刻度文字显示角度
  68. curveChart->addAxis(axisX,Qt::AlignBottom);
  69. xGuideSeries->attachAxis(axisX);
  70. yGuideSeries->attachAxis(axisX);
  71. fitPointsSeriesS->attachAxis(axisX);
  72. tipSeries->attachAxis(axisX);
  73. QValueAxis* axisY = new QValueAxis;
  74. axisY->setRange(0, 500);
  75. axisY->setTickCount(11);
  76. axisY->setLabelFormat("%d");
  77. curveChart->addAxis(axisY,Qt::AlignLeft);
  78. xGuideSeries->attachAxis(axisY);
  79. yGuideSeries->attachAxis(axisY);
  80. fitPointsSeriesS->attachAxis(axisY);
  81. tipSeries->attachAxis(axisY);
  82. // axisX->setGridLineVisible(false); //隐藏背景网格X轴框线
  83. // axisY->setGridLineVisible(false); //隐藏背景网格Y轴框线
  84. curveChart->legend()->markers()[0]->setVisible(false);
  85. curveChart->legend()->markers()[1]->setVisible(false);
  86. curveChart->legend()->markers()[2]->setVisible(false);
  87. curveChart->legend()->markers()[3]->setVisible(false);
  88. curveChartView->setRenderHint(QPainter::Antialiasing); //除锯齿
  89. connect(curveChartView, &FitCurveChartView::signalMouseEvent, this, &FitCurveDialog::theSlotMouseEvent);
  90. connect(curveChartView, &FitCurveChartView::signalWheelEvent, this, &FitCurveDialog::theSlotWheelEvent);
  91. ui->chartLayout->addWidget(curveChartView);
  92. }
  93. void FitCurveDialog::theSlotMouseEvent(int eventId, QMouseEvent *event) {
  94. if (eventId == 0){ //单击按下
  95. isPressed = true;
  96. QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
  97. pressedPoint = mouseEvent->pos();
  98. } else if (eventId == 1) { //鼠标移动
  99. if (isPressed) {
  100. QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
  101. curveChart->scroll(-(mouseEvent->pos().x() - pressedPoint.x()) / 10,
  102. (mouseEvent->pos().y() - pressedPoint.y()) / 10);
  103. updateXYGuideLine();
  104. }
  105. } else if (eventId == 2) { //单击抬起
  106. isPressed = false;
  107. } else if (eventId == 3) { //双击
  108. resetZoomAndScroll();
  109. updateXYGuideLine();
  110. }
  111. }
  112. void FitCurveDialog::theSlotWheelEvent(QWheelEvent *event) {
  113. int delta = event->angleDelta().y();
  114. if (delta > 0) {
  115. curveChart->zoom(0.95);
  116. } else {
  117. curveChart->zoom(1.05);
  118. }
  119. updateXYGuideLine();
  120. }
  121. void FitCurveDialog::updateXYGuideLine() {
  122. if (tipSeries->points().size() > 0) {
  123. QVector<int> axisRanges = getAxisRanges();
  124. QVector<QPointF> xGuideList, yGuideList;
  125. int tempX = tipSeries->points()[0].x();
  126. int tempY = tipSeries->points()[0].y();
  127. xGuideList.append(QPointF(tempX, axisRanges[2]));
  128. xGuideList.append(QPointF(tempX, tempY));
  129. yGuideList.append(QPointF(axisRanges[0], tempY));
  130. yGuideList.append(QPointF(tempX, tempY));
  131. xGuideSeries->replace(xGuideList);
  132. yGuideSeries->replace(yGuideList);
  133. }
  134. }
  135. void FitCurveDialog::resetZoomAndScroll() {
  136. curveChart->zoomReset();
  137. QList<QAbstractAxis*> axesX, axesY;
  138. axesX = curveChart->axes(Qt::Horizontal);
  139. axesY = curveChart->axes(Qt::Vertical);
  140. QValueAxis *curAxisX = (QValueAxis*)axesX[0];
  141. QValueAxis *curAxisY = (QValueAxis*)axesY[0];
  142. curAxisX->setRange(0, 20000);
  143. curAxisY->setRange(0, 500);
  144. }
  145. QVector<int> FitCurveDialog::getAxisRanges() {
  146. QList<QAbstractAxis*> axesX, axesY;
  147. axesX = curveChart->axes(Qt::Horizontal);
  148. axesY = curveChart->axes(Qt::Vertical);
  149. QValueAxis *curAxisX = (QValueAxis*)axesX[0];
  150. QValueAxis *curAxisY = (QValueAxis*)axesY[0];
  151. QVector<int> ranges = {int(curAxisX->min()), int(curAxisX->max()), int(curAxisY->min()), int(curAxisY->max())};
  152. return ranges;
  153. }
  154. FitCurveDialog::~FitCurveDialog()
  155. {
  156. delete ui;
  157. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/504601
推荐阅读
相关标签
  

闽ICP备14008679号