You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

CurveWidget.cpp 11 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. #include "CurveWidget.h"
  2. CurveWidget::CurveWidget(QWidget* parent)
  3. : QWidget(parent)
  4. , m_iWgtWidth(0)
  5. , m_iWgtHeight(0)
  6. , m_pPlotTitle(nullptr)
  7. , m_pRubberBand(nullptr)
  8. , m_pCPGraph(nullptr)
  9. , m_dYMax(0.0)
  10. , m_dYMin(0.0)
  11. , m_uiParseStatus(0)
  12. , m_bRefTime(false)
  13. {
  14. ui.setupUi(this);
  15. setWindowFlags(Qt::FramelessWindowHint);
  16. initCurvePlot();
  17. // connect(ui.pb_changeCoord,&QPushButton::clicked,this,&CurveWidget::changeCoord); //坐标切换
  18. connect(ui.pb_zoomCoordY, &QPushButton::clicked, this, &CurveWidget::zoomCoordY); // Y轴缩放
  19. connect(ui.pb_resetCoord, &QPushButton::clicked, this, &CurveWidget::resetCoord); // 坐标重置
  20. connect(ui.pb_hide, &QPushButton::clicked, this, &CurveWidget::hideWindow); // 隐藏窗口
  21. connect(&m_timer, &QTimer::timeout, this, &CurveWidget::refreshCurve);
  22. ui.le_curValue->setEnabled(false); // 当前值窗口
  23. // ui.pb_changeCoord->setToolTip("坐标转换:\n实时解析时改变X轴显示方式");
  24. ui.pb_zoomCoordY->setToolTip("Y轴缩放:\n点击按钮,利用Ctrl+鼠标滚轮进行Y轴缩放");
  25. ui.pb_resetCoord->setToolTip("坐标重置");
  26. ui.pb_hide->setToolTip("关闭窗口");
  27. // ui.pb_changeCoord->setEnabled(false); //坐标切换
  28. ui.pb_zoomCoordY->setEnabled(false); // Y轴缩放
  29. ui.pb_resetCoord->setEnabled(false); // 坐标重置
  30. }
  31. CurveWidget::~CurveWidget()
  32. {
  33. delete m_pCurveInfo;
  34. m_pCurveInfo = nullptr;
  35. }
  36. void CurveWidget::initCurvePlot()
  37. {
  38. m_axisRange.axisMinX = 0.0;
  39. m_axisRange.axisMaxX = 100.0;
  40. m_axisRange.axisMinY = 0.0;
  41. m_axisRange.axisMaxY = 100.0;
  42. m_pPlotTitle = new QCPPlotTitle(ui.wgt_curvePlot);
  43. m_pPlotTitle->setFont(QFont("sans", 12, QFont::Bold));
  44. ui.wgt_curvePlot->xAxis->setRange(m_axisRange.axisMinX, m_axisRange.axisMaxX);
  45. ui.wgt_curvePlot->yAxis->setRange(m_axisRange.axisMinY, m_axisRange.axisMaxY);
  46. ui.wgt_curvePlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); // 支持拖拽和缩放
  47. ui.wgt_curvePlot->axisRect()->setRangeZoom(Qt::Horizontal); // 水平缩放
  48. ui.wgt_curvePlot->xAxis->setLabel("时间(ms)");
  49. ui.wgt_curvePlot->plotLayout()->insertRow(0);
  50. ui.wgt_curvePlot->plotLayout()->addElement(0, 0, m_pPlotTitle);
  51. m_pRubberBand = new QRubberBand(QRubberBand::Rectangle, ui.wgt_curvePlot);
  52. connect(ui.wgt_curvePlot, &QCustomPlot::mousePress, this, &CurveWidget::mousePressEvent);
  53. connect(ui.wgt_curvePlot, &QCustomPlot::mouseMove, this, &CurveWidget::mouseMoveEvent);
  54. connect(ui.wgt_curvePlot, &QCustomPlot::mouseRelease, this, &CurveWidget::mouseReleaseEvent);
  55. }
  56. void CurveWidget::setParam(CurveInfo*& curveInfo)
  57. {
  58. m_pCurveInfo = curveInfo;
  59. strTitle = curveInfo->m_strTitle;
  60. m_usModel = curveInfo->m_usCurveModel;
  61. m_count = curveInfo->m_curveCount;
  62. ui.lb_curveName->setText(strTitle);
  63. ui.wgt_curvePlot->yAxis->setLabel(strTitle);
  64. // 添加曲线
  65. m_pCPGraph = ui.wgt_curvePlot->addGraph();
  66. QPen pen;
  67. pen.setColor(curveInfo->m_curveColor); // 曲线颜色
  68. m_pCPGraph->setPen(pen);
  69. m_pCPGraph->setVisible(true);
  70. if (m_usModel == 4) { // 状态量
  71. m_pCPGraph->setLineStyle((QCPGraph::lsStepLeft)); // 阶梯型曲线
  72. }
  73. curveInfo->m_pGPGraph = m_pCPGraph;
  74. }
  75. void CurveWidget::keyPressEvent(QKeyEvent* event)
  76. {
  77. if (event->key() == Qt::Key_Control) {
  78. ui.wgt_curvePlot->axisRect()->setRangeZoom(Qt::Vertical);
  79. }
  80. }
  81. void CurveWidget::keyReleaseEvent(QKeyEvent* event)
  82. {
  83. if (event->key() == Qt::Key_Control) {
  84. ui.wgt_curvePlot->axisRect()->setRangeZoom(Qt::Horizontal);
  85. }
  86. }
  87. void CurveWidget::resizeEvent(QResizeEvent* event)
  88. {
  89. QSize size = event->size();
  90. m_iWgtWidth = size.width();
  91. m_iWgtHeight = size.height();
  92. resizeSubControl(m_iWgtWidth, m_iWgtHeight);
  93. }
  94. void CurveWidget::resizeSubControl(int width, int height)
  95. {
  96. ui.wgt_background->setGeometry(0, 0, width, height);
  97. // 曲线信息
  98. int iHeight = ui.lb_curveInfo->height();
  99. ui.lb_curveInfo->setGeometry(0, 0, width, iHeight);
  100. ui.lb_curveInfo->setStyleSheet("background-color:rgb(113,113,113)");
  101. // 关闭按钮
  102. QRect rect = ui.pb_hide->geometry();
  103. ui.pb_hide->setGeometry(width - 5 - rect.width(), rect.y(), rect.width(), rect.height());
  104. // 重置按钮
  105. rect = ui.pb_resetCoord->geometry();
  106. ui.pb_resetCoord->setGeometry(width - (5 + rect.width()) * 2, rect.y(), rect.width(),
  107. rect.height());
  108. // Y轴缩放
  109. rect = ui.pb_zoomCoordY->geometry();
  110. ui.pb_zoomCoordY->setGeometry(width - (5 + rect.width()) * 3, rect.y(), rect.width(),
  111. rect.height());
  112. // 坐标切换
  113. // rect = ui.pb_changeCoord->geometry();
  114. // ui.pb_changeCoord->setGeometry(width - (5 + rect.width()) * 4, rect.y(), rect.width(),
  115. // rect.height()); 曲线控件
  116. ui.wgt_curvePlot->setGeometry(0, iHeight, width, height - iHeight);
  117. }
  118. void CurveWidget::mousePressEvent(QMouseEvent* event)
  119. {
  120. if (event->button() == Qt::RightButton) {
  121. m_originPoint = event->pos(); // 鼠标原始位置
  122. m_pRubberBand->setGeometry(QRect(m_originPoint, QSize()));
  123. m_pRubberBand->show();
  124. }
  125. }
  126. void CurveWidget::mouseMoveEvent(QMouseEvent* event)
  127. {
  128. if (event->buttons() && Qt::RightButton) {
  129. if (m_pRubberBand->isVisible()) {
  130. QPoint point = event->pos();
  131. m_pRubberBand->setGeometry(QRect(m_originPoint, event->pos()).normalized());
  132. }
  133. }
  134. int axisX = event->pos().x();
  135. int axisY = event->pos().y();
  136. double coordX = ui.wgt_curvePlot->xAxis->pixelToCoord((double)axisX);
  137. double coordY = ui.wgt_curvePlot->yAxis->pixelToCoord((double)axisY);
  138. QString strTip = QString("x:%1,y:%2")
  139. .arg(QString::number(coordX, 10, 1))
  140. .arg(QString::number(coordY, 10, 3));
  141. QToolTip::showText(cursor().pos(), strTip, ui.wgt_curvePlot);
  142. }
  143. void CurveWidget::mouseReleaseEvent(QMouseEvent* event)
  144. {
  145. if (m_pRubberBand->isVisible()) {
  146. const QRect zoomRect = m_pRubberBand->geometry();
  147. int xp1, yp1, xp2, yp2;
  148. zoomRect.getCoords(&xp1, &yp1, &xp2, &yp2);
  149. double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0;
  150. // 把鼠标坐标点 转换为QCustomPlot内部坐标值(pixelToCoord 函数)
  151. // coordToPixel 函数与之相反 是把内部坐标值 转换为外部坐标点
  152. x1 = ui.wgt_curvePlot->xAxis->pixelToCoord(xp1);
  153. x2 = ui.wgt_curvePlot->xAxis->pixelToCoord(xp2);
  154. y1 = ui.wgt_curvePlot->yAxis->pixelToCoord(yp1);
  155. y2 = ui.wgt_curvePlot->yAxis->pixelToCoord(yp2);
  156. ui.wgt_curvePlot->xAxis->setRange(x1, x2);
  157. ui.wgt_curvePlot->yAxis->setRange(y1, y2);
  158. m_pRubberBand->hide();
  159. ui.wgt_curvePlot->replot();
  160. }
  161. }
  162. /*
  163. //坐标切换
  164. void CurveWidget::changeCoord() {
  165. if (m_pCurveInfo->m_bIsZeroX == false) { //false:固定间距显示
  166. m_pCurveInfo->m_bIsZeroX = true;
  167. }
  168. else if (m_pCurveInfo->m_bIsZeroX == true) { //true:从零开始显示
  169. m_pCurveInfo->m_bIsZeroX = false;
  170. }
  171. }*/
  172. // Y轴缩放
  173. void CurveWidget::zoomCoordY()
  174. {
  175. ui.wgt_curvePlot->replot();
  176. }
  177. // 坐标重置
  178. void CurveWidget::resetCoord()
  179. {
  180. // 修改坐标轴范围
  181. ui.wgt_curvePlot->xAxis->setRange(m_axisRange.axisMinX, m_axisRange.axisMaxX);
  182. ui.wgt_curvePlot->yAxis->setRange(m_dYMin, m_dYMax);
  183. ui.wgt_curvePlot->replot();
  184. }
  185. // 隐藏窗口
  186. void CurveWidget::hideWindow()
  187. {
  188. emit hideCurveWidget(m_count);
  189. }
  190. void CurveWidget::startRefresh(bool status)
  191. {
  192. if (status == true) {
  193. m_timer.start(500);
  194. } else if (status == false) {
  195. m_timer.stop();
  196. }
  197. }
  198. void CurveWidget::refreshCurve()
  199. {
  200. int iSize = m_pCurveInfo->m_vecAxisY.size();
  201. if (iSize == 0) {
  202. return;
  203. }
  204. m_mutex.lock();
  205. if (m_uiParseStatus == 2) { // 在线解析
  206. double dValue = (double)m_pCurveInfo->m_vecAxisY.at(iSize - 1);
  207. QString strValue = QString::number(dValue, 'f', 3);
  208. ui.le_curValue->setText(strValue); // 当前值窗口
  209. if (m_pCurveInfo->m_vecAxisX.size() > 3000) {
  210. m_pCurveInfo->m_vecAxisX.erase(m_pCurveInfo->m_vecAxisX.begin(),
  211. m_pCurveInfo->m_vecAxisX.end() - 2000);
  212. }
  213. if (m_pCurveInfo->m_vecAxisY.size() > 3000) {
  214. m_pCurveInfo->m_vecAxisY.erase(m_pCurveInfo->m_vecAxisY.begin(),
  215. m_pCurveInfo->m_vecAxisY.end() - 2000);
  216. }
  217. }
  218. m_pCurveInfo->m_pGPGraph->setData(m_pCurveInfo->m_vecAxisX, m_pCurveInfo->m_vecAxisY);
  219. m_axisRange.axisMinX = m_pCurveInfo->minX;
  220. m_axisRange.axisMaxX = m_pCurveInfo->maxX;
  221. m_axisRange.axisMaxY = m_pCurveInfo->maxY;
  222. m_axisRange.axisMinY = m_pCurveInfo->minY;
  223. ui.wgt_curvePlot->xAxis->setRange(m_axisRange.axisMinX, m_axisRange.axisMaxX);
  224. m_dYMin = m_axisRange.axisMinY - (m_axisRange.axisMaxY - m_axisRange.axisMinY) / 2.0;
  225. m_dYMax = m_axisRange.axisMaxY + (m_axisRange.axisMaxY - m_axisRange.axisMinY) / 2.0;
  226. ui.wgt_curvePlot->yAxis->setRange(m_dYMin, m_dYMax);
  227. ui.wgt_curvePlot->replot();
  228. m_mutex.unlock();
  229. }
  230. void CurveWidget::clearWidget()
  231. {
  232. m_pCurveInfo->m_vecAxisX.clear();
  233. m_pCurveInfo->m_vecAxisY.clear();
  234. m_pCurveInfo->m_pGPGraph->clearData();
  235. m_axisRange.axisMinX = 0.0;
  236. m_axisRange.axisMaxX = 100.0;
  237. m_axisRange.axisMinY = 0.0;
  238. m_axisRange.axisMaxY = 100.0;
  239. ui.wgt_curvePlot->xAxis->setLabel("时间(ms)");
  240. ui.wgt_curvePlot->xAxis->setRange(m_axisRange.axisMinX, m_axisRange.axisMaxX);
  241. ui.wgt_curvePlot->yAxis->setRange(m_axisRange.axisMinY, m_axisRange.axisMaxY);
  242. ui.wgt_curvePlot->replot();
  243. }
  244. void CurveWidget::parseFinished()
  245. {
  246. refreshCurve();
  247. }
  248. void CurveWidget::setParseStatus(unsigned int status)
  249. {
  250. m_uiParseStatus = status;
  251. if (m_uiParseStatus == 0 || m_uiParseStatus == 1) { // 无任务解析或离线解析
  252. // ui.pb_changeCoord->setEnabled(false); //坐标切换
  253. ui.pb_zoomCoordY->setEnabled(true); // Y轴缩放
  254. ui.pb_resetCoord->setEnabled(true); // 坐标重置
  255. } else if (m_uiParseStatus == 2) { // 实时解析
  256. // ui.pb_changeCoord->setEnabled(true); //坐标切换
  257. ui.pb_zoomCoordY->setEnabled(false); // Y轴缩放
  258. ui.pb_resetCoord->setEnabled(false); // 坐标重置
  259. }
  260. }