TIMEDIFF可以做now()-staytime > 5 minute

本文探讨了MySQL中使用TIMEDIFF函数进行时间差比较的方法,并提供了一种更有效的替代方案,即利用SUBDATE函数配合NOW()和INTERVAL关键字来实现。
一个 mysql的sql 需要删除 staytime字段(类型 时间) 与现在 时间 相差5分的记录

now()-staytime > 5 minute

我开始 选用的是TIMEDIFF 但是发现无法 应用 》5 分这个条件
例如
> SELECT TIMEDIFF('2000:01:01 00:00:00', -> '2000:01:01 00:00:00.000001'); -> '-00:00:00.000001'
这里不知道哦啊如何表达 》 5分的条件

后来我用
staytime< subdate(now, INTERVAL 5 MINUTE);
可以 完成

想知道TIMEDIFF可以做吗 ? 或者还有其他方法?
SQL code

mysql> SELECT TIMEDIFF('2010-10-10 10:10:00','2010-10-10 10:15:00');
+-------------------------------------------------------+
| TIMEDIFF('2010-10-10 10:10:00','2010-10-10 10:15:00') |
+-------------------------------------------------------+
| -00:05:00 |
+-------------------------------------------------------+
1 row in set (0.05 sec)

mysql> SELECT TIMEDIFF('2010-10-10 10:20:00','2010-10-10 10:15:00');
+-------------------------------------------------------+
| TIMEDIFF('2010-10-10 10:20:00','2010-10-10 10:15:00') |
+-------------------------------------------------------+
| 00:05:00 |
+-------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

回答者:zuoxingyu - 2010-10-14 18:23:31
SQL code

mysql> SELECT minute(TIMEDIFF('2010-10-10 10:20:00','2010-10-10 10:15:00'));
+---------------------------------------------------------------+
| minute(TIMEDIFF('2010-10-10 10:20:00','2010-10-10 10:15:00')) |
+---------------------------------------------------------------+
| 5 |
+---------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

回答者:zuoxingyu - 2010-10-14 18:24:37
where staytime<now()-interval 5 minute

应该如上这样,这样的话,还可以使用staytime上的索引。
回答者:ACMAIN_CHM - 2010-10-14 18:57:18
感谢楼上 where staytime<now()-interval 5 minute 这个按照道理是 最好

回答
flowchart TD A[开始] --> B[读取轨迹数据CSV文件] B --> C[数据预处理<br/>按ID和时间戳排序] C --> D[按轨迹ID分组] D --> E[初始化结果数据集] E --> F[选择当前轨迹组] F --> G[设置索引i=0] G --> H{i < 轨迹长度-1?} H -->|否| W[处理下一个轨迹组] H -->|是| I[获取第i个点作为基准点<br/>记录经纬度坐标] I --> J[预测性去重检查] J --> K{第i+2个点与<br/>基准点位置相同?} K -->|是| L[删除第i+1个点<br/>重新索引] K -->|否| M{第i+3个点与<br/>基准点位置相同?} L --> M M -->|是| N[删除第i+2个点<br/>重新索引] M -->|否| O[开始连续性扫描<br/>j=i+1, last_equal_j=i<br/>unequal_count=0] N --> O O --> P{j < 轨迹长度?} P -->|否| S{last_equal_j > i?} P -->|是| Q{第j个点与<br/>基准点位置相同?} Q -->|是| R[更新last_equal_j = j<br/>j = j + 1] Q -->|否| T[unequal_count += 1<br/>j = j + 1] R --> P T --> U{unequal_count == 2?} U -->|是| S U -->|否| P S -->|是| V[计算停留时间<br/>timeDiff = time[last_equal_j] - time[i]<br/>保存记录到结果集<br/>i = last_equal_j + 1] S -->|否| X[索引递增<br/>i = i + 1] V --> H X --> H W --> Y{还有未处理的轨迹组?} Y -->|是| F Y -->|否| Z[输出处理结果到CSV文件] Z --> AA[结束] style A fill:#e1f5fe style AA fill:#e8f5e8 style J fill:#fff3e0 style K fill:#fff3e0 style M fill:#fff3e0 style Q fill:#f3e5f5 style S fill:#ffebee style V fill:#e8f5e8 style X fill:#ffebee Error: Error: Parse error on line 34: Error: Parse error on line 67: ...<br/>timeDiff = time[last_equal_j] - tim -----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'SQS'
最新发布
08-26
#include "mainwindow.h" #include "ui_Mainwindow.h" #include "qcustomplot.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // 创建主工具栏 mainToolBar = new QToolBar("主工具栏", this); mainToolBar->setMovable(false); // 禁止工具栏移动 addToolBar(Qt::TopToolBarArea, mainToolBar); ui->customPlot->addGraph(); ui->customPlot->graph(0)->setPen(QPen(Qt::blue)); // 线条颜色为蓝色 // 生成一些数据点 QVector<double> x(251), y0(251); for (int i=0; i<251; ++i) { x[i] = i; y0[i] = qExp(-i/150.0)*qCos(i/10.0); // 指数衰减的余弦函数 } // 配置右轴和上轴显示刻度但不显示标签 ui->customPlot->xAxis2->setVisible(true); ui->customPlot->xAxis2->setTickLabels(false); ui->customPlot->yAxis2->setVisible(true); ui->customPlot->yAxis2->setTickLabels(false); // 使左轴和下轴的范围变化同步到右轴和上轴 connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->xAxis2, SLOT(setRange(QCPRange))); connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->yAxis2, SLOT(setRange(QCPRange))); // 将数据点传递给图形 ui->customPlot->graph(0)->setData(x, y0); // 自动调整坐标轴范围以适应图形 ui->customPlot->graph(0)->rescaleAxes(); // 允许用户通过鼠标拖动坐标轴范围、使用鼠标滚轮缩放以及通过点击选择图形 ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); // 计算图表中心位置 double xCenter = (ui->customPlot->xAxis->range().lower + ui->customPlot->xAxis->range().upper) / 2; double yCenter = (ui->customPlot->yAxis->range().lower + ui->customPlot->yAxis->range().upper) / 2; // 初始化第一组纵向和横向光标线 verticalLine1 = new QCPItemStraightLine(ui->customPlot); verticalLine1->setPen(QPen(Qt::red)); verticalLine1->point1->setCoords(0, ui->customPlot->yAxis->range().lower); verticalLine1->point2->setCoords(0, ui->customPlot->yAxis->range().upper); verticalLine1->setVisible(false); horizontalLine1 = new QCPItemStraightLine(ui->customPlot); horizontalLine1->setPen(QPen(Qt::red)); horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, 0); horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, 0); horizontalLine1->setVisible(false); // 初始化第一组标签 verticalLabel1 = new QCPItemText(ui->customPlot); verticalLabel1->setLayer("overlay"); // 确保标签显示在最上层 verticalLabel1->setClipToAxisRect(false); verticalLabel1->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter); verticalLabel1->position->setType(QCPItemPosition::ptAxisRectRatio); verticalLabel1->position->setCoords(0, 0); // 初始位置 verticalLabel1->setText("Time: 0"); verticalLabel1->setFont(QFont(font().family(), 9)); verticalLabel1->setPen(QPen(Qt::red)); verticalLabel1->setBrush(QBrush(Qt::white)); verticalLabel1->setVisible(false); horizontalLabel1 = new QCPItemText(ui->customPlot); horizontalLabel1->setLayer("overlay"); horizontalLabel1->setClipToAxisRect(false); horizontalLabel1->setPositionAlignment(Qt::AlignLeft|Qt::AlignVCenter); horizontalLabel1->position->setType(QCPItemPosition::ptAxisRectRatio); horizontalLabel1->position->setCoords(0, 0); // 初始位置 horizontalLabel1->setText("Voltage: 0"); horizontalLabel1->setFont(QFont(font().family(), 9)); horizontalLabel1->setPen(QPen(Qt::red)); horizontalLabel1->setBrush(QBrush(Qt::white)); horizontalLabel1->setVisible(false); // 初始化第二组纵向和横向光标线 verticalLine2 = new QCPItemStraightLine(ui->customPlot); verticalLine2->setPen(QPen(Qt::green)); // verticalLine2->point1->setCoords(0, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(0, ui->customPlot->yAxis->range().upper); verticalLine2->point1->setCoords(xCenter + 10, ui->customPlot->yAxis->range().lower); verticalLine2->point2->setCoords(xCenter + 10, ui->customPlot->yAxis->range().upper); verticalLine2->setVisible(false); horizontalLine2 = new QCPItemStraightLine(ui->customPlot); horizontalLine2->setPen(QPen(Qt::green)); // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, 0); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, 0); horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, yCenter + 0.2); horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, yCenter + 0.2); horizontalLine2->setVisible(false); // 初始化第二组标签 verticalLabel2 = new QCPItemText(ui->customPlot); verticalLabel2->setLayer("overlay"); // 确保标签显示在最上层 verticalLabel2->setClipToAxisRect(false); verticalLabel2->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter); verticalLabel2->position->setType(QCPItemPosition::ptAxisRectRatio); verticalLabel2->position->setCoords(0, 0); // 初始位置 verticalLabel2->setText("Time: 0"); verticalLabel2->setFont(QFont(font().family(), 9)); verticalLabel2->setPen(QPen(Qt::green)); verticalLabel2->setBrush(QBrush(Qt::white)); verticalLabel2->setVisible(false); horizontalLabel2 = new QCPItemText(ui->customPlot); horizontalLabel2->setLayer("overlay"); horizontalLabel2->setClipToAxisRect(false); horizontalLabel2->setPositionAlignment(Qt::AlignLeft|Qt::AlignVCenter); horizontalLabel2->position->setType(QCPItemPosition::ptAxisRectRatio); horizontalLabel2->position->setCoords(0, 0); // 初始位置 horizontalLabel2->setText("Voltage: 0"); horizontalLabel2->setFont(QFont(font().family(), 9)); horizontalLabel2->setPen(QPen(Qt::green)); horizontalLabel2->setBrush(QBrush(Qt::white)); horizontalLabel2->setVisible(false); // 创建差值标签 diffLabel = new QCPItemText(ui->customPlot); diffLabel->setLayer("overlay"); diffLabel->setClipToAxisRect(false); diffLabel->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter); diffLabel->position->setType(QCPItemPosition::ptAxisRectRatio); diffLabel->position->setCoords(0.5, 0.05); // 顶部中间位置 diffLabel->setFont(QFont(font().family(), 10, QFont::Bold)); diffLabel->setPen(QPen(Qt::black)); diffLabel->setBrush(QBrush(Qt::white)); diffLabel->setVisible(false); // 初始化状态 isVerticalDragging1 = false; isHorizontalDragging1 = false; isVerticalDragging2 = false; isHorizontalDragging2 = false; cursorEditMode = false; verticalLine1Created = false; horizontalLine1Created = false; verticalLine2Created = false; horizontalLine2Created = false; // 设置光标模式动作 cursorModeAction = new QAction("光标模式", this); cursorModeAction->setIcon(QIcon(":/images/line_icon/rewind-button.png")); cursorModeAction->setCheckable(true); mainToolBar->addAction(cursorModeAction); connect(cursorModeAction, &QAction::triggered, this, &MainWindow::on_cursorModeAction_triggered); ui->statusbar->showMessage("光标编辑模式已关闭"); // 连接鼠标移动事件到 mouseMoveEvent 槽函数 connect(ui->customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMoveEvent(QMouseEvent*))); connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePressEvent(QMouseEvent*))); connect(ui->customPlot, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(mouseReleaseEvent(QMouseEvent*))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_cursorModeAction_triggered() { cursorEditMode = cursorModeAction->isChecked(); if (cursorEditMode) { ui->customPlot->setInteractions(QCP::iSelectPlottables); ui->statusbar->showMessage("光标编辑模式已开启 - 左键添加/移动垂直光标,右键添加/移动水平光标"); } else { ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); ui->statusbar->showMessage("光标编辑模式已关闭"); verticalLine1->setVisible(false); horizontalLine1->setVisible(false); verticalLabel1->setVisible(false); horizontalLabel1->setVisible(false); verticalLine2->setVisible(false); horizontalLine2->setVisible(false); verticalLabel2->setVisible(false); horizontalLabel2->setVisible(false); diffLabel->setVisible(false); verticalLine1Created = false; horizontalLine1Created = false; verticalLine2Created = false; horizontalLine2Created = false; activeVerticalLine = nullptr; activeVerticalLabel = nullptr; activeHorizontalLine = nullptr; activeHorizontalLabel = nullptr; } ui->customPlot->replot(); } // void MainWindow::mousePressEvent(QMouseEvent *event) // { // if (cursorEditMode) { // double x = ui->customPlot->xAxis->pixelToCoord(event->x()); // double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // // 检查点击是否靠近第一组垂直光标 // if (qAbs(x - verticalLine1->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { // isVerticalDragging1 = true; // verticalLine1->setVisible(true); // verticalLabel1->setVisible(true); // verticalLine1Created = true; // } // // 检查点击是否靠近第一组水平光标 // if (qAbs(y - horizontalLine1->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { // isHorizontalDragging1 = true; // horizontalLine1->setVisible(true); // horizontalLabel1->setVisible(true); // horizontalLine1Created = true; // } // // 检查点击是否靠近第二组垂直光标 // if (qAbs(x - verticalLine2->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { // isVerticalDragging2 = true; // verticalLine2->setVisible(true); // verticalLabel2->setVisible(true); // verticalLine2Created = true; // } // // 检查点击是否靠近第二组水平光标 // if (qAbs(y - horizontalLine2->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { // isHorizontalDragging2 = true; // horizontalLine2->setVisible(true); // horizontalLabel2->setVisible(true); // horizontalLine2Created = true; // } // // 如果点击在空白处,根据鼠标位置设置新光标位置 // if (event->button() == Qt::LeftButton) { // if (!verticalLine1Created) { // verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // verticalLine1->setVisible(true); // verticalLabel1->setVisible(true); // isVerticalDragging1 = true; // verticalLine1Created = true; // } else if (!verticalLine2Created) { // verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // verticalLine2->setVisible(true); // verticalLabel2->setVisible(true); // isVerticalDragging2 = true; // verticalLine2Created = true; // } // } else if (event->button() == Qt::RightButton) { // if (!horizontalLine1Created) { // horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // horizontalLine1->setVisible(true); // horizontalLabel1->setVisible(true); // isHorizontalDragging1 = true; // horizontalLine1Created = true; // } else if (!horizontalLine2Created) { // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // horizontalLine2->setVisible(true); // horizontalLabel2->setVisible(true); // isHorizontalDragging2 = true; // horizontalLine2Created = true; // } // } // ui->customPlot->replot(); // } else { // QMainWindow::mousePressEvent(event); // } // } // void MainWindow::mousePressEvent(QMouseEvent *event) // { // if (cursorEditMode) { // double x = ui->customPlot->xAxis->pixelToCoord(event->x()); // double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // // 检查点击是否靠近垂直光标 // if (qAbs(x - verticalLine1->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { // activeVerticalLine = verticalLine1; // activeVerticalLabel = verticalLabel1; // isVerticalDragging1 = true; // verticalLine1->setVisible(true); // verticalLabel1->setVisible(true); // verticalLine1Created = true; // } else if (qAbs(x - verticalLine2->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { // activeVerticalLine = verticalLine2; // activeVerticalLabel = verticalLabel2; // isVerticalDragging2 = true; // verticalLine2->setVisible(true); // verticalLabel2->setVisible(true); // verticalLine2Created = true; // } // // 检查点击是否靠近水平光标 // if (qAbs(y - horizontalLine1->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { // activeHorizontalLine = horizontalLine1; // activeHorizontalLabel = horizontalLabel1; // isHorizontalDragging1 = true; // horizontalLine1->setVisible(true); // horizontalLabel1->setVisible(true); // horizontalLine1Created = true; // } else if (qAbs(y - horizontalLine2->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { // activeHorizontalLine = horizontalLine2; // activeHorizontalLabel = horizontalLabel2; // isHorizontalDragging2 = true; // horizontalLine2->setVisible(true); // horizontalLabel2->setVisible(true); // horizontalLine2Created = true; // } // // 如果点击在空白处,根据鼠标位置设置新光标位置 // if (event->button() == Qt::LeftButton) { // if (!verticalLine1Created) { // activeVerticalLine = verticalLine1; // activeVerticalLabel = verticalLabel1; // verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // verticalLine1->setVisible(true); // verticalLabel1->setVisible(true); // isVerticalDragging1 = true; // verticalLine1Created = true; // } else if (!verticalLine2Created) { // activeVerticalLine = verticalLine2; // activeVerticalLabel = verticalLabel2; // verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // verticalLine2->setVisible(true); // verticalLabel2->setVisible(true); // isVerticalDragging2 = true; // verticalLine2Created = true; // } // } else if (event->button() == Qt::RightButton) { // if (!horizontalLine1Created) { // activeHorizontalLine = horizontalLine1; // activeHorizontalLabel = horizontalLabel1; // horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // horizontalLine1->setVisible(true); // horizontalLabel1->setVisible(true); // isHorizontalDragging1 = true; // horizontalLine1Created = true; // } else if (!horizontalLine2Created) { // activeHorizontalLine = horizontalLine2; // activeHorizontalLabel = horizontalLabel2; // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // horizontalLine2->setVisible(true); // horizontalLabel2->setVisible(true); // isHorizontalDragging2 = true; // horizontalLine2Created = true; // } // } // ui->customPlot->replot(); // } else { // QMainWindow::mousePressEvent(event); // } // } void MainWindow::mousePressEvent(QMouseEvent *event) { if (cursorEditMode) { double x = ui->customPlot->xAxis->pixelToCoord(event->x()); double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // 重置拖动状态 isVerticalDragging1 = false; isHorizontalDragging1 = false; isVerticalDragging2 = false; isHorizontalDragging2 = false; // 检查垂直光标(仅左键处理) if (event->button() == Qt::LeftButton) { if (verticalLine1Created && qAbs(x - verticalLine1->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { isVerticalDragging1 = true; } else if (verticalLine2Created && qAbs(x - verticalLine2->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { isVerticalDragging2 = true; } } // 检查水平光标(仅右键处理) if (event->button() == Qt::RightButton) { if (horizontalLine1Created && qAbs(y - horizontalLine1->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { isHorizontalDragging1 = true; } else if (horizontalLine2Created && qAbs(y - horizontalLine2->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { isHorizontalDragging2 = true; } } // 如果点击在空白处,根据鼠标位置设置新光标位置 if (event->button() == Qt::LeftButton) { if (!verticalLine1Created) { verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); verticalLine1->setVisible(true); verticalLabel1->setVisible(true); isVerticalDragging1 = true; verticalLine1Created = true; // 更新标签文本 //verticalLabel1->setText(QString("Time: %1").arg(x, 0, 'f', 2)); updateVerticalCursorLabel(verticalLabel1, x); } else if (!verticalLine2Created) { verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); verticalLine2->setVisible(true); verticalLabel2->setVisible(true); isVerticalDragging2 = true; verticalLine2Created = true; // 更新标签文本 //verticalLabel1->setText(QString("Time: %1").arg(x, 0, 'f', 2)); updateVerticalCursorLabel(verticalLabel2, x); } } else if (event->button() == Qt::RightButton) { if (!horizontalLine1Created) { horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); horizontalLine1->setVisible(true); horizontalLabel1->setVisible(true); isHorizontalDragging1 = true; horizontalLine1Created = true; // 更新标签文本 //horizontalLabel1->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); updateHorizontalCursorLabel(horizontalLabel1, y); } else if (!horizontalLine2Created) { horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); horizontalLine2->setVisible(true); horizontalLabel2->setVisible(true); isHorizontalDragging2 = true; horizontalLine2Created = true; // 更新标签文本 //horizontalLabel1->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); updateHorizontalCursorLabel(horizontalLabel2, y); } } ui->customPlot->replot(); } else { QMainWindow::mousePressEvent(event); } } // void MainWindow::mouseMoveEvent(QMouseEvent *event) // { // if (cursorEditMode) { // double x = ui->customPlot->xAxis->pixelToCoord(event->x()); // double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // if (isVerticalDragging1) { // verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // // 更新垂直标签位置和内容 // verticalLabel1->position->setCoords( // (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), // 1.0 // ); // verticalLabel1->setText(QString("Time: %1").arg(x, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Time: %1").arg(x, 0, 'f', 2)); // } // if (isHorizontalDragging1) { // horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // // 更新水平标签位置和内容 // horizontalLabel1->position->setCoords( // 0.0, // (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size() // ); // horizontalLabel1->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Voltage: %1").arg(y, 0, 'f', 2)); // } // if (isVerticalDragging2) { // verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // // 更新垂直标签位置和内容 // verticalLabel2->position->setCoords( // (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), // 1.0 // ); // verticalLabel2->setText(QString("Time: %1").arg(x, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Time: %1").arg(x, 0, 'f', 2)); // } // if (isHorizontalDragging2) { // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // // 更新水平标签位置和内容 // horizontalLabel2->position->setCoords( // 0.0, // (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size() // ); // horizontalLabel2->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Voltage: %1").arg(y, 0, 'f', 2)); // } // ui->customPlot->replot(); // calculateAndDisplayDifferences(); // } else { // QMainWindow::mouseMoveEvent(event); // } // } // void MainWindow::mouseMoveEvent(QMouseEvent *event) // { // if (cursorEditMode) { // double x = ui->customPlot->xAxis->pixelToCoord(event->x()); // double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // if (isVerticalDragging1 || isVerticalDragging2) { // activeVerticalLine->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // activeVerticalLine->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // // 更新垂直标签位置和内容 // activeVerticalLabel->position->setCoords( // (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), // 1.0 // ); // activeVerticalLabel->setText(QString("Time: %1").arg(x, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Time: %1").arg(x, 0, 'f', 2)); // } // if (isHorizontalDragging1 || isHorizontalDragging2) { // activeHorizontalLine->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // activeHorizontalLine->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // // 更新水平标签位置和内容 // activeHorizontalLabel->position->setCoords( // 0.0, // (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size() // ); // activeHorizontalLabel->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Voltage: %1").arg(y, 0, 'f', 2)); // } // ui->customPlot->replot(); // calculateAndDisplayDifferences(); // } else { // QMainWindow::mouseMoveEvent(event); // } // } void MainWindow::mouseMoveEvent(QMouseEvent *event) { if (cursorEditMode) { double x = ui->customPlot->xAxis->pixelToCoord(event->x()); double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // 独立处理垂直光标拖动 if (isVerticalDragging1) { // verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); verticalLine1->point1->setCoords(x, verticalLine1->point1->coords().y()); verticalLine1->point2->setCoords(x, verticalLine1->point2->coords().y()); verticalLabel1->position->setCoords( (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), 1.0); verticalLabel1->setText(QString("Time: %1").arg(x, 0, 'f', 2)); } else if (isVerticalDragging2) { // verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); verticalLine2->point1->setCoords(x, verticalLine2->point1->coords().y()); verticalLine2->point2->setCoords(x, verticalLine2->point2->coords().y()); verticalLabel2->position->setCoords( (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), 1.0); verticalLabel2->setText(QString("Time: %1").arg(x, 0, 'f', 2)); } // 独立处理水平光标拖动 if (isHorizontalDragging1) { // horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); horizontalLine1->point1->setCoords(horizontalLine1->point1->coords().x(), y); horizontalLine1->point2->setCoords(horizontalLine2->point2->coords().x(), y); horizontalLabel1->position->setCoords( 0.0, (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size()); horizontalLabel1->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); } else if (isHorizontalDragging2) { // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); horizontalLine2->point1->setCoords(horizontalLine2->point1->coords().x(), y); horizontalLine2->point2->setCoords(horizontalLine2->point2->coords().x(), y); horizontalLabel2->position->setCoords( 0.0, (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size()); horizontalLabel2->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); } ui->customPlot->replot(); calculateAndDisplayDifferences(); qDebug() << "Creating horizontal line 2 at y:" << y; } else { QMainWindow::mouseMoveEvent(event); } } void MainWindow::mouseReleaseEvent(QMouseEvent *event) { isVerticalDragging1 = false; isHorizontalDragging1 = false; isVerticalDragging2 = false; isHorizontalDragging2 = false; if (!cursorEditMode) { QMainWindow::mouseReleaseEvent(event); } } void MainWindow::calculateAndDisplayDifferences() { static double lastTimeDiff = 0; static double lastVoltageDiff = 0; QString statusMessage; bool needsUpdate = false; // 计算并显示时间差值 if (verticalLine1->visible() && verticalLine2->visible()) { double timeDiff = qAbs(verticalLine1->point1->coords().x() - verticalLine2->point1->coords().x()); if (!qFuzzyCompare(timeDiff, lastTimeDiff)) { statusMessage += QString("ΔT: %1 ").arg(timeDiff, 0, 'f', 2); lastTimeDiff = timeDiff; needsUpdate = true; } } // 计算并显示电压差值 if (horizontalLine1->visible() && horizontalLine2->visible()) { double voltageDiff = qAbs(horizontalLine1->point1->coords().y() - horizontalLine2->point1->coords().y()); if (!qFuzzyCompare(voltageDiff, lastVoltageDiff)) { statusMessage += QString("ΔV: %1").arg(voltageDiff, 0, 'f', 2); lastVoltageDiff = voltageDiff; needsUpdate = true; } } // 仅在需要时更新UI if (needsUpdate) { ui->statusbar->showMessage(statusMessage); if (diffLabel) { diffLabel->setText(statusMessage); diffLabel->setVisible(!statusMessage.isEmpty()); } ui->customPlot->replot(QCustomPlot::rpQueuedReplot); } } void MainWindow::updateVerticalCursorLabel(QCPItemText *label, double x) { label->position->setCoords( (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), 1.0); label->setText(QString("Time: %1").arg(x, 0, 'f', 2)); } void MainWindow::updateHorizontalCursorLabel(QCPItemText *label, double y) { label->position->setCoords( 0.0, (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size()); label->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); qDebug() << "Setting horizontal label 2 text to voltage:" << y; } #include "mainwindow.h" #include "ui_Mainwindow.h" #include "qcustomplot.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // 创建主工具栏 mainToolBar = new QToolBar("主工具栏", this); mainToolBar->setMovable(false); // 禁止工具栏移动 addToolBar(Qt::TopToolBarArea, mainToolBar); ui->customPlot->addGraph(); ui->customPlot->graph(0)->setPen(QPen(Qt::blue)); // 线条颜色为蓝色 // 生成一些数据点 QVector<double> x(251), y0(251); for (int i=0; i<251; ++i) { x[i] = i; y0[i] = qExp(-i/150.0)*qCos(i/10.0); // 指数衰减的余弦函数 } // 配置右轴和上轴显示刻度但不显示标签 ui->customPlot->xAxis2->setVisible(true); ui->customPlot->xAxis2->setTickLabels(false); ui->customPlot->yAxis2->setVisible(true); ui->customPlot->yAxis2->setTickLabels(false); // 使左轴和下轴的范围变化同步到右轴和上轴 connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->xAxis2, SLOT(setRange(QCPRange))); connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->yAxis2, SLOT(setRange(QCPRange))); // 将数据点传递给图形 ui->customPlot->graph(0)->setData(x, y0); // 自动调整坐标轴范围以适应图形 ui->customPlot->graph(0)->rescaleAxes(); // 允许用户通过鼠标拖动坐标轴范围、使用鼠标滚轮缩放以及通过点击选择图形 ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); // 计算图表中心位置 double xCenter = (ui->customPlot->xAxis->range().lower + ui->customPlot->xAxis->range().upper) / 2; double yCenter = (ui->customPlot->yAxis->range().lower + ui->customPlot->yAxis->range().upper) / 2; // 初始化第一组纵向和横向光标线 verticalLine1 = new QCPItemStraightLine(ui->customPlot); verticalLine1->setPen(QPen(Qt::red)); verticalLine1->point1->setCoords(0, ui->customPlot->yAxis->range().lower); verticalLine1->point2->setCoords(0, ui->customPlot->yAxis->range().upper); verticalLine1->setVisible(false); horizontalLine1 = new QCPItemStraightLine(ui->customPlot); horizontalLine1->setPen(QPen(Qt::red)); horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, 0); horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, 0); horizontalLine1->setVisible(false); // 初始化第一组标签 verticalLabel1 = new QCPItemText(ui->customPlot); verticalLabel1->setLayer("overlay"); // 确保标签显示在最上层 verticalLabel1->setClipToAxisRect(false); verticalLabel1->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter); verticalLabel1->position->setType(QCPItemPosition::ptAxisRectRatio); verticalLabel1->position->setCoords(0, 0); // 初始位置 verticalLabel1->setText("Time: 0"); verticalLabel1->setFont(QFont(font().family(), 9)); verticalLabel1->setPen(QPen(Qt::red)); verticalLabel1->setBrush(QBrush(Qt::white)); verticalLabel1->setVisible(false); horizontalLabel1 = new QCPItemText(ui->customPlot); horizontalLabel1->setLayer("overlay"); horizontalLabel1->setClipToAxisRect(false); horizontalLabel1->setPositionAlignment(Qt::AlignLeft|Qt::AlignVCenter); horizontalLabel1->position->setType(QCPItemPosition::ptAxisRectRatio); horizontalLabel1->position->setCoords(0, 0); // 初始位置 horizontalLabel1->setText("Voltage: 0"); horizontalLabel1->setFont(QFont(font().family(), 9)); horizontalLabel1->setPen(QPen(Qt::red)); horizontalLabel1->setBrush(QBrush(Qt::white)); horizontalLabel1->setVisible(false); // 初始化第二组纵向和横向光标线 verticalLine2 = new QCPItemStraightLine(ui->customPlot); verticalLine2->setPen(QPen(Qt::green)); // verticalLine2->point1->setCoords(0, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(0, ui->customPlot->yAxis->range().upper); verticalLine2->point1->setCoords(xCenter + 10, ui->customPlot->yAxis->range().lower); verticalLine2->point2->setCoords(xCenter + 10, ui->customPlot->yAxis->range().upper); verticalLine2->setVisible(false); horizontalLine2 = new QCPItemStraightLine(ui->customPlot); horizontalLine2->setPen(QPen(Qt::green)); // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, 0); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, 0); horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, yCenter + 0.2); horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, yCenter + 0.2); horizontalLine2->setVisible(false); // 初始化第二组标签 verticalLabel2 = new QCPItemText(ui->customPlot); verticalLabel2->setLayer("overlay"); // 确保标签显示在最上层 verticalLabel2->setClipToAxisRect(false); verticalLabel2->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter); verticalLabel2->position->setType(QCPItemPosition::ptAxisRectRatio); verticalLabel2->position->setCoords(0, 0); // 初始位置 verticalLabel2->setText("Time: 0"); verticalLabel2->setFont(QFont(font().family(), 9)); verticalLabel2->setPen(QPen(Qt::green)); verticalLabel2->setBrush(QBrush(Qt::white)); verticalLabel2->setVisible(false); horizontalLabel2 = new QCPItemText(ui->customPlot); horizontalLabel2->setLayer("overlay"); horizontalLabel2->setClipToAxisRect(false); horizontalLabel2->setPositionAlignment(Qt::AlignLeft|Qt::AlignVCenter); horizontalLabel2->position->setType(QCPItemPosition::ptAxisRectRatio); horizontalLabel2->position->setCoords(0, 0); // 初始位置 horizontalLabel2->setText("Voltage: 0"); horizontalLabel2->setFont(QFont(font().family(), 9)); horizontalLabel2->setPen(QPen(Qt::green)); horizontalLabel2->setBrush(QBrush(Qt::white)); horizontalLabel2->setVisible(false); // 创建差值标签 diffLabel = new QCPItemText(ui->customPlot); diffLabel->setLayer("overlay"); diffLabel->setClipToAxisRect(false); diffLabel->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter); diffLabel->position->setType(QCPItemPosition::ptAxisRectRatio); diffLabel->position->setCoords(0.5, 0.05); // 顶部中间位置 diffLabel->setFont(QFont(font().family(), 10, QFont::Bold)); diffLabel->setPen(QPen(Qt::black)); diffLabel->setBrush(QBrush(Qt::white)); diffLabel->setVisible(false); // 初始化状态 isVerticalDragging1 = false; isHorizontalDragging1 = false; isVerticalDragging2 = false; isHorizontalDragging2 = false; cursorEditMode = false; verticalLine1Created = false; horizontalLine1Created = false; verticalLine2Created = false; horizontalLine2Created = false; // 设置光标模式动作 cursorModeAction = new QAction("光标模式", this); cursorModeAction->setIcon(QIcon(":/images/line_icon/rewind-button.png")); cursorModeAction->setCheckable(true); mainToolBar->addAction(cursorModeAction); connect(cursorModeAction, &QAction::triggered, this, &MainWindow::on_cursorModeAction_triggered); ui->statusbar->showMessage("光标编辑模式已关闭"); // 连接鼠标移动事件到 mouseMoveEvent 槽函数 connect(ui->customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMoveEvent(QMouseEvent*))); connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePressEvent(QMouseEvent*))); connect(ui->customPlot, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(mouseReleaseEvent(QMouseEvent*))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_cursorModeAction_triggered() { cursorEditMode = cursorModeAction->isChecked(); if (cursorEditMode) { ui->customPlot->setInteractions(QCP::iSelectPlottables); ui->statusbar->showMessage("光标编辑模式已开启 - 左键添加/移动垂直光标,右键添加/移动水平光标"); } else { ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); ui->statusbar->showMessage("光标编辑模式已关闭"); verticalLine1->setVisible(false); horizontalLine1->setVisible(false); verticalLabel1->setVisible(false); horizontalLabel1->setVisible(false); verticalLine2->setVisible(false); horizontalLine2->setVisible(false); verticalLabel2->setVisible(false); horizontalLabel2->setVisible(false); diffLabel->setVisible(false); verticalLine1Created = false; horizontalLine1Created = false; verticalLine2Created = false; horizontalLine2Created = false; activeVerticalLine = nullptr; activeVerticalLabel = nullptr; activeHorizontalLine = nullptr; activeHorizontalLabel = nullptr; } ui->customPlot->replot(); } // void MainWindow::mousePressEvent(QMouseEvent *event) // { // if (cursorEditMode) { // double x = ui->customPlot->xAxis->pixelToCoord(event->x()); // double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // // 检查点击是否靠近第一组垂直光标 // if (qAbs(x - verticalLine1->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { // isVerticalDragging1 = true; // verticalLine1->setVisible(true); // verticalLabel1->setVisible(true); // verticalLine1Created = true; // } // // 检查点击是否靠近第一组水平光标 // if (qAbs(y - horizontalLine1->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { // isHorizontalDragging1 = true; // horizontalLine1->setVisible(true); // horizontalLabel1->setVisible(true); // horizontalLine1Created = true; // } // // 检查点击是否靠近第二组垂直光标 // if (qAbs(x - verticalLine2->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { // isVerticalDragging2 = true; // verticalLine2->setVisible(true); // verticalLabel2->setVisible(true); // verticalLine2Created = true; // } // // 检查点击是否靠近第二组水平光标 // if (qAbs(y - horizontalLine2->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { // isHorizontalDragging2 = true; // horizontalLine2->setVisible(true); // horizontalLabel2->setVisible(true); // horizontalLine2Created = true; // } // // 如果点击在空白处,根据鼠标位置设置新光标位置 // if (event->button() == Qt::LeftButton) { // if (!verticalLine1Created) { // verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // verticalLine1->setVisible(true); // verticalLabel1->setVisible(true); // isVerticalDragging1 = true; // verticalLine1Created = true; // } else if (!verticalLine2Created) { // verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // verticalLine2->setVisible(true); // verticalLabel2->setVisible(true); // isVerticalDragging2 = true; // verticalLine2Created = true; // } // } else if (event->button() == Qt::RightButton) { // if (!horizontalLine1Created) { // horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // horizontalLine1->setVisible(true); // horizontalLabel1->setVisible(true); // isHorizontalDragging1 = true; // horizontalLine1Created = true; // } else if (!horizontalLine2Created) { // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // horizontalLine2->setVisible(true); // horizontalLabel2->setVisible(true); // isHorizontalDragging2 = true; // horizontalLine2Created = true; // } // } // ui->customPlot->replot(); // } else { // QMainWindow::mousePressEvent(event); // } // } // void MainWindow::mousePressEvent(QMouseEvent *event) // { // if (cursorEditMode) { // double x = ui->customPlot->xAxis->pixelToCoord(event->x()); // double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // // 检查点击是否靠近垂直光标 // if (qAbs(x - verticalLine1->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { // activeVerticalLine = verticalLine1; // activeVerticalLabel = verticalLabel1; // isVerticalDragging1 = true; // verticalLine1->setVisible(true); // verticalLabel1->setVisible(true); // verticalLine1Created = true; // } else if (qAbs(x - verticalLine2->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { // activeVerticalLine = verticalLine2; // activeVerticalLabel = verticalLabel2; // isVerticalDragging2 = true; // verticalLine2->setVisible(true); // verticalLabel2->setVisible(true); // verticalLine2Created = true; // } // // 检查点击是否靠近水平光标 // if (qAbs(y - horizontalLine1->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { // activeHorizontalLine = horizontalLine1; // activeHorizontalLabel = horizontalLabel1; // isHorizontalDragging1 = true; // horizontalLine1->setVisible(true); // horizontalLabel1->setVisible(true); // horizontalLine1Created = true; // } else if (qAbs(y - horizontalLine2->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { // activeHorizontalLine = horizontalLine2; // activeHorizontalLabel = horizontalLabel2; // isHorizontalDragging2 = true; // horizontalLine2->setVisible(true); // horizontalLabel2->setVisible(true); // horizontalLine2Created = true; // } // // 如果点击在空白处,根据鼠标位置设置新光标位置 // if (event->button() == Qt::LeftButton) { // if (!verticalLine1Created) { // activeVerticalLine = verticalLine1; // activeVerticalLabel = verticalLabel1; // verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // verticalLine1->setVisible(true); // verticalLabel1->setVisible(true); // isVerticalDragging1 = true; // verticalLine1Created = true; // } else if (!verticalLine2Created) { // activeVerticalLine = verticalLine2; // activeVerticalLabel = verticalLabel2; // verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // verticalLine2->setVisible(true); // verticalLabel2->setVisible(true); // isVerticalDragging2 = true; // verticalLine2Created = true; // } // } else if (event->button() == Qt::RightButton) { // if (!horizontalLine1Created) { // activeHorizontalLine = horizontalLine1; // activeHorizontalLabel = horizontalLabel1; // horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // horizontalLine1->setVisible(true); // horizontalLabel1->setVisible(true); // isHorizontalDragging1 = true; // horizontalLine1Created = true; // } else if (!horizontalLine2Created) { // activeHorizontalLine = horizontalLine2; // activeHorizontalLabel = horizontalLabel2; // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // horizontalLine2->setVisible(true); // horizontalLabel2->setVisible(true); // isHorizontalDragging2 = true; // horizontalLine2Created = true; // } // } // ui->customPlot->replot(); // } else { // QMainWindow::mousePressEvent(event); // } // } void MainWindow::mousePressEvent(QMouseEvent *event) { if (cursorEditMode) { double x = ui->customPlot->xAxis->pixelToCoord(event->x()); double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // 重置拖动状态 isVerticalDragging1 = false; isHorizontalDragging1 = false; isVerticalDragging2 = false; isHorizontalDragging2 = false; // 检查垂直光标(仅左键处理) if (event->button() == Qt::LeftButton) { if (verticalLine1Created && qAbs(x - verticalLine1->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { isVerticalDragging1 = true; } else if (verticalLine2Created && qAbs(x - verticalLine2->point1->coords().x()) < CURSOR_DISTANCE_THRESHOLD) { isVerticalDragging2 = true; } } // 检查水平光标(仅右键处理) if (event->button() == Qt::RightButton) { if (horizontalLine1Created && qAbs(y - horizontalLine1->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { isHorizontalDragging1 = true; } else if (horizontalLine2Created && qAbs(y - horizontalLine2->point1->coords().y()) < CURSOR_DISTANCE_THRESHOLD) { isHorizontalDragging2 = true; } } // 如果点击在空白处,根据鼠标位置设置新光标位置 if (event->button() == Qt::LeftButton) { if (!verticalLine1Created) { verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); verticalLine1->setVisible(true); verticalLabel1->setVisible(true); isVerticalDragging1 = true; verticalLine1Created = true; // 更新标签文本 //verticalLabel1->setText(QString("Time: %1").arg(x, 0, 'f', 2)); updateVerticalCursorLabel(verticalLabel1, x); } else if (!verticalLine2Created) { verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); verticalLine2->setVisible(true); verticalLabel2->setVisible(true); isVerticalDragging2 = true; verticalLine2Created = true; // 更新标签文本 //verticalLabel1->setText(QString("Time: %1").arg(x, 0, 'f', 2)); updateVerticalCursorLabel(verticalLabel2, x); } } else if (event->button() == Qt::RightButton) { if (!horizontalLine1Created) { horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); horizontalLine1->setVisible(true); horizontalLabel1->setVisible(true); isHorizontalDragging1 = true; horizontalLine1Created = true; // 更新标签文本 //horizontalLabel1->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); updateHorizontalCursorLabel(horizontalLabel1, y); } else if (!horizontalLine2Created) { horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); horizontalLine2->setVisible(true); horizontalLabel2->setVisible(true); isHorizontalDragging2 = true; horizontalLine2Created = true; // 更新标签文本 //horizontalLabel1->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); updateHorizontalCursorLabel(horizontalLabel2, y); } } ui->customPlot->replot(); } else { QMainWindow::mousePressEvent(event); } } // void MainWindow::mouseMoveEvent(QMouseEvent *event) // { // if (cursorEditMode) { // double x = ui->customPlot->xAxis->pixelToCoord(event->x()); // double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // if (isVerticalDragging1) { // verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // // 更新垂直标签位置和内容 // verticalLabel1->position->setCoords( // (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), // 1.0 // ); // verticalLabel1->setText(QString("Time: %1").arg(x, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Time: %1").arg(x, 0, 'f', 2)); // } // if (isHorizontalDragging1) { // horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // // 更新水平标签位置和内容 // horizontalLabel1->position->setCoords( // 0.0, // (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size() // ); // horizontalLabel1->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Voltage: %1").arg(y, 0, 'f', 2)); // } // if (isVerticalDragging2) { // verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // // 更新垂直标签位置和内容 // verticalLabel2->position->setCoords( // (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), // 1.0 // ); // verticalLabel2->setText(QString("Time: %1").arg(x, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Time: %1").arg(x, 0, 'f', 2)); // } // if (isHorizontalDragging2) { // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // // 更新水平标签位置和内容 // horizontalLabel2->position->setCoords( // 0.0, // (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size() // ); // horizontalLabel2->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Voltage: %1").arg(y, 0, 'f', 2)); // } // ui->customPlot->replot(); // calculateAndDisplayDifferences(); // } else { // QMainWindow::mouseMoveEvent(event); // } // } // void MainWindow::mouseMoveEvent(QMouseEvent *event) // { // if (cursorEditMode) { // double x = ui->customPlot->xAxis->pixelToCoord(event->x()); // double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // if (isVerticalDragging1 || isVerticalDragging2) { // activeVerticalLine->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // activeVerticalLine->point2->setCoords(x, ui->customPlot->yAxis->range().upper); // // 更新垂直标签位置和内容 // activeVerticalLabel->position->setCoords( // (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), // 1.0 // ); // activeVerticalLabel->setText(QString("Time: %1").arg(x, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Time: %1").arg(x, 0, 'f', 2)); // } // if (isHorizontalDragging1 || isHorizontalDragging2) { // activeHorizontalLine->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // activeHorizontalLine->point2->setCoords(ui->customPlot->xAxis->range().upper, y); // // 更新水平标签位置和内容 // activeHorizontalLabel->position->setCoords( // 0.0, // (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size() // ); // activeHorizontalLabel->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); // ui->statusbar->showMessage(QString("Voltage: %1").arg(y, 0, 'f', 2)); // } // ui->customPlot->replot(); // calculateAndDisplayDifferences(); // } else { // QMainWindow::mouseMoveEvent(event); // } // } void MainWindow::mouseMoveEvent(QMouseEvent *event) { if (cursorEditMode) { double x = ui->customPlot->xAxis->pixelToCoord(event->x()); double y = ui->customPlot->yAxis->pixelToCoord(event->y()); // 独立处理垂直光标拖动 if (isVerticalDragging1) { // verticalLine1->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine1->point2->setCoords(x, ui->customPlot->yAxis->range().upper); verticalLine1->point1->setCoords(x, verticalLine1->point1->coords().y()); verticalLine1->point2->setCoords(x, verticalLine1->point2->coords().y()); verticalLabel1->position->setCoords( (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), 1.0); verticalLabel1->setText(QString("Time: %1").arg(x, 0, 'f', 2)); } else if (isVerticalDragging2) { // verticalLine2->point1->setCoords(x, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(x, ui->customPlot->yAxis->range().upper); verticalLine2->point1->setCoords(x, verticalLine2->point1->coords().y()); verticalLine2->point2->setCoords(x, verticalLine2->point2->coords().y()); verticalLabel2->position->setCoords( (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), 1.0); verticalLabel2->setText(QString("Time: %1").arg(x, 0, 'f', 2)); } // 独立处理水平光标拖动 if (isHorizontalDragging1) { // horizontalLine1->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine1->point2->setCoords(ui->customPlot->xAxis->range().upper, y); horizontalLine1->point1->setCoords(horizontalLine1->point1->coords().x(), y); horizontalLine1->point2->setCoords(horizontalLine2->point2->coords().x(), y); horizontalLabel1->position->setCoords( 0.0, (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size()); horizontalLabel1->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); } else if (isHorizontalDragging2) { // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, y); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, y); horizontalLine2->point1->setCoords(horizontalLine2->point1->coords().x(), y); horizontalLine2->point2->setCoords(horizontalLine2->point2->coords().x(), y); horizontalLabel2->position->setCoords( 0.0, (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size()); horizontalLabel2->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); } ui->customPlot->replot(); calculateAndDisplayDifferences(); qDebug() << "Creating horizontal line 2 at y:" << y; } else { QMainWindow::mouseMoveEvent(event); } } void MainWindow::mouseReleaseEvent(QMouseEvent *event) { isVerticalDragging1 = false; isHorizontalDragging1 = false; isVerticalDragging2 = false; isHorizontalDragging2 = false; if (!cursorEditMode) { QMainWindow::mouseReleaseEvent(event); } } void MainWindow::calculateAndDisplayDifferences() { static double lastTimeDiff = 0; static double lastVoltageDiff = 0; QString statusMessage; bool needsUpdate = false; // 计算并显示时间差值 if (verticalLine1->visible() && verticalLine2->visible()) { double timeDiff = qAbs(verticalLine1->point1->coords().x() - verticalLine2->point1->coords().x()); if (!qFuzzyCompare(timeDiff, lastTimeDiff)) { statusMessage += QString("ΔT: %1 ").arg(timeDiff, 0, 'f', 2); lastTimeDiff = timeDiff; needsUpdate = true; } } // 计算并显示电压差值 if (horizontalLine1->visible() && horizontalLine2->visible()) { double voltageDiff = qAbs(horizontalLine1->point1->coords().y() - horizontalLine2->point1->coords().y()); if (!qFuzzyCompare(voltageDiff, lastVoltageDiff)) { statusMessage += QString("ΔV: %1").arg(voltageDiff, 0, 'f', 2); lastVoltageDiff = voltageDiff; needsUpdate = true; } } // 仅在需要时更新UI if (needsUpdate) { ui->statusbar->showMessage(statusMessage); if (diffLabel) { diffLabel->setText(statusMessage); diffLabel->setVisible(!statusMessage.isEmpty()); } ui->customPlot->replot(QCustomPlot::rpQueuedReplot); } } void MainWindow::updateVerticalCursorLabel(QCPItemText *label, double x) { label->position->setCoords( (x - ui->customPlot->xAxis->range().lower) / ui->customPlot->xAxis->range().size(), 1.0); label->setText(QString("Time: %1").arg(x, 0, 'f', 2)); } void MainWindow::updateHorizontalCursorLabel(QCPItemText *label, double y) { label->position->setCoords( 0.0, (y - ui->customPlot->yAxis->range().lower) / ui->customPlot->yAxis->range().size()); label->setText(QString("Voltage: %1").arg(y, 0, 'f', 2)); qDebug() << "Setting horizontal label 2 text to voltage:" << y; } 在QCustomPlot中实现双光标测量两点之间的差值
07-10
#include "mainwindow.h" #include "ui_Mainwindow.h" #include "qcustomplot.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建主工具栏 mainToolBar = new QToolBar("主工具栏", this); mainToolBar->setMovable(false); // 禁止工具栏移动 addToolBar(Qt::TopToolBarArea, mainToolBar); ui->customplot->addGraph(); ui->customplot->graph(0)->setPen(QPen(Qt::darkCyan)); // 线条颜色为靛蓝色 // 生成一些数据点 QVector<double> x(251), y0(251); for (int i=0; i<251; ++i) { x[i] = i; y0[i] = qExp(-i/150.0)*qCos(i/10.0); // 指数衰减的余弦函数 } // 配置右轴和上轴显示刻度但不显示标签 ui->customplot->xAxis2->setVisible(true); ui->customplot->xAxis2->setTickLabels(false); ui->customplot->yAxis2->setVisible(true); ui->customplot->yAxis2->setTickLabels(false); // 使左轴和下轴的范围变化同步到右轴和上轴 connect(ui->customplot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customplot->xAxis2, SLOT(setRange(QCPRange))); connect(ui->customplot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customplot->yAxis2, SLOT(setRange(QCPRange))); // 将数据点传递给图形 ui->customplot->graph(0)->setData(x, y0); // 自动调整坐标轴范围以适应图形 ui->customplot->graph(0)->rescaleAxes(); // 允许用户通过鼠标拖动坐标轴范围、使用鼠标滚轮缩放以及通过点击选择图形 ui->customplot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); // 计算图表中心位置 double xCenter = (ui->customplot->xAxis->range().lower + ui->customplot->xAxis->range().upper) / 2; double yCenter = (ui->customplot->yAxis->range().lower + ui->customplot->yAxis->range().upper) / 2; // 初始化垂直光标1 verticalLine1 = new QCPItemStraightLine(ui->customplot); verticalLine1->setPen(QPen(Qt::red, 1, Qt::SolidLine)); verticalLine1->point1->setCoords(0, ui->customplot->yAxis->range().lower); verticalLine1->point2->setCoords(0, ui->customplot->yAxis->range().upper); verticalLine1->setVisible(false); // 初始化垂直光标1的标签 verticalLabel1 = new QCPItemText(ui->customplot); verticalLabel1->setLayer("overlay"); // 确保标签显示在最上层 verticalLabel1->setClipToAxisRect(false); verticalLabel1->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter); verticalLabel1->position->setType(QCPItemPosition::ptAxisRectRatio); verticalLabel1->position->setCoords(0, 0); // 初始位置 verticalLabel1->setText("Time: 0"); verticalLabel1->setFont(QFont(font().family(), 9)); verticalLabel1->setPen(QPen(Qt::red)); verticalLabel1->setBrush(QBrush(Qt::white)); verticalLabel1->setVisible(false); // 初始化垂直光标2 verticalLine2 = new QCPItemStraightLine(ui->customplot); verticalLine2->setPen(QPen(Qt::green, 1, Qt::SolidLine)); // verticalLine2->point1->setCoords(0, ui->customPlot->yAxis->range().lower); // verticalLine2->point2->setCoords(0, ui->customPlot->yAxis->range().upper); verticalLine2->point1->setCoords(xCenter + 10, ui->customplot->yAxis->range().lower); verticalLine2->point2->setCoords(xCenter + 10, ui->customplot->yAxis->range().upper); verticalLine2->setVisible(false); // 初始化垂直光标2的标签 verticalLabel2 = new QCPItemText(ui->customplot); verticalLabel2->setLayer("overlay"); // 确保标签显示在最上层 verticalLabel2->setClipToAxisRect(false); verticalLabel2->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter); verticalLabel2->position->setType(QCPItemPosition::ptAxisRectRatio); verticalLabel2->position->setCoords(0, 0); // 初始位置 verticalLabel2->setText("Time: 0"); verticalLabel2->setFont(QFont(font().family(), 9)); verticalLabel2->setPen(QPen(Qt::red)); verticalLabel2->setBrush(QBrush(Qt::white)); verticalLabel2->setVisible(false); // 初始化水平光标1 horizontalLine1 = new QCPItemStraightLine(ui->customplot); horizontalLine1->setPen(QPen(Qt::magenta, 1, Qt::SolidLine)); horizontalLine1->point1->setCoords(ui->customplot->xAxis->range().lower, 0); horizontalLine1->point2->setCoords(ui->customplot->xAxis->range().upper, 0); horizontalLine1->setVisible(false); // 初始化水平光标1的标签 horizontalLabel1 = new QCPItemText(ui->customplot); horizontalLabel1->setLayer("overlay"); horizontalLabel1->setClipToAxisRect(false);// 允许标签超出轴矩形范围 // 设置位置类型为绘图坐标 horizontalLabel1->position->setType(QCPItemPosition::ptPlotCoords); // 确保标签使用绘图坐标系统 // 初始位置在绘图区域的左侧,Y坐标为0(后面会被更新) horizontalLabel1->position->setCoords(ui->customplot->xAxis->range().lower - 5, 0); // 设置对齐方式:右对齐(因为我们要放在左侧外部,所以文字向右对齐,然后通过偏移向左移动) horizontalLabel1->setPositionAlignment(Qt::AlignRight | Qt::AlignVCenter); horizontalLabel1->setText("Voltage: 0"); horizontalLabel1->setFont(QFont(font().family(), 9)); horizontalLabel1->setPen(QPen(Qt::red)); horizontalLabel1->setBrush(QBrush(Qt::white)); horizontalLabel1->setVisible(false); // 初始化水平光标2 horizontalLine2 = new QCPItemStraightLine(ui->customplot); horizontalLine2->setPen(QPen(Qt::blue, 1, Qt::SolidLine)); // horizontalLine2->point1->setCoords(ui->customPlot->xAxis->range().lower, 0); // horizontalLine2->point2->setCoords(ui->customPlot->xAxis->range().upper, 0); horizontalLine2->point1->setCoords(ui->customplot->xAxis->range().lower, yCenter + 0.2); horizontalLine2->point2->setCoords(ui->customplot->xAxis->range().upper, yCenter + 0.2); horizontalLine2->setVisible(false); // 初始化水平光标2的标签 horizontalLabel2 = new QCPItemText(ui->customplot); horizontalLabel2->setLayer("overlay"); // 确保标签显示在最上层 horizontalLabel2->setClipToAxisRect(false);// 允许标签超出轴矩形范围 horizontalLabel2->position->setType(QCPItemPosition::ptPlotCoords); // 确保标签使用绘图坐标系统 // 初始位置在绘图区域的左侧,Y坐标为0(后面会被更新) horizontalLabel2->position->setCoords(ui->customplot->xAxis->range().lower - 5, 0); // 设置对齐方式:右对齐(因为我们要放在左侧外部,所以文字向右对齐,然后通过偏移向左移动) horizontalLabel2->setPositionAlignment(Qt::AlignRight | Qt::AlignVCenter); horizontalLabel2->setText("Voltage: 0"); horizontalLabel2->setFont(QFont(font().family(), 9)); horizontalLabel2->setPen(QPen(Qt::red)); horizontalLabel2->setBrush(QBrush(Qt::white)); horizontalLabel2->setVisible(false); // 初始化差值标签 diffLabel = new QCPItemText(ui->customplot); diffLabel->setLayer("overlay"); diffLabel->setClipToAxisRect(false); diffLabel->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter); diffLabel->position->setType(QCPItemPosition::ptAxisRectRatio); diffLabel->position->setCoords(0.5, 0.05); // 顶部中间 diffLabel->setText("ΔT: 0.0, ΔV: 0.0"); diffLabel->setFont(QFont(font().family(), 10, QFont::Bold)); diffLabel->setPen(QPen(Qt::black)); diffLabel->setBrush(QBrush(Qt::white)); diffLabel->setVisible(false); // 初始化最大值标签 maxLabel = new QCPItemText(ui->customplot); maxLabel->setLayer("overlay"); maxLabel->setClipToAxisRect(false); maxLabel->setPositionAlignment(Qt::AlignTop|Qt::AlignRight); maxLabel->position->setType(QCPItemPosition::ptAxisRectRatio); maxLabel->position->setCoords(0.95, 0.05); // 右上角 maxLabel->setText("Max: 0.0"); maxLabel->setFont(QFont(font().family(), 10, QFont::Bold)); maxLabel->setPen(QPen(Qt::black)); maxLabel->setBrush(QBrush(Qt::white)); maxLabel->setVisible(false); // 初始化最小值标签 minLabel = new QCPItemText(ui->customplot); minLabel->setLayer("overlay"); minLabel->setClipToAxisRect(false); minLabel->setPositionAlignment(Qt::AlignBottom|Qt::AlignRight); minLabel->position->setType(QCPItemPosition::ptAxisRectRatio); minLabel->position->setCoords(0.95, 0.95); // 右下角 minLabel->setText("Min: 0.0"); minLabel->setFont(QFont(font().family(), 10, QFont::Bold)); minLabel->setPen(QPen(Qt::black)); minLabel->setBrush(QBrush(Qt::white)); minLabel->setVisible(false); // 初始化状态 isVerticalDragging1 = false; isHorizontalDragging1 = false; isVerticalDragging2 = false; isHorizontalDragging2 = false; cursorEditMode = false; verticalLine1Created = false; horizontalLine1Created = false; verticalLine2Created = false; horizontalLine2Created = false; measurementModeEnabled = false; // 初始化波形测量模式状态 currentMeasurementMode = NoMeasurement; cursorModeAction = new QAction("Cursor Mode", this); //cursorModeAction->setIcon(QIcon(":/images/line_icon/rewind-button.png")); cursorModeAction->setIcon(QIcon(":/images/line_icon_set_text/rewind-button.png")); cursorModeAction->setCheckable(true); mainToolBar->addAction(cursorModeAction); connect(cursorModeAction, &QAction::triggered, this, &MainWindow::onCursorModeToggled); // 添加测量模式下拉列表 ui->measurementModeComboBox = new QComboBox(this); ui->measurementModeComboBox->addItem("无测量模式"); ui->measurementModeComboBox->addItem("电压测量"); ui->measurementModeComboBox->addItem("时间测量"); ui->measurementModeComboBox->setVisible(false); mainToolBar->addWidget(ui->measurementModeComboBox); //测量模式下拉列表选项改变信号槽连接 connect(ui->measurementModeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::onMeasurementModeChanged); // 连接鼠标移动事件到 mouseMoveEvent 槽函数 connect(ui->customplot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMoveEvent(QMouseEvent*))); connect(ui->customplot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePressEvent(QMouseEvent*))); connect(ui->customplot, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(mouseReleaseEvent(QMouseEvent*))); // 查找并标记特征点 QVector<int> peaks = findPeaks(y0); QVector<int> valleys = findValleys(y0); QVector<int> zeroCrossings = findZeroCrossings(y0); // 标记峰值 for (int peakIndex : peaks) { double xValue = x[peakIndex]; double yValue = y0[peakIndex]; QCPItemTracer *peakTracer = new QCPItemTracer(ui->customplot); peakTracer->setGraph(ui->customplot->graph(0)); peakTracer->setGraphKey(xValue); peakTracer->setStyle(QCPItemTracer::tsCircle); peakTracer->setPen(QPen(Qt::red)); peakTracer->setBrush(Qt::red); peakTracer->setSize(8); } // 标记谷值 for (int valleyIndex : valleys) { double xValue = x[valleyIndex]; double yValue = y0[valleyIndex]; QCPItemTracer *valleyTracer = new QCPItemTracer(ui->customplot); valleyTracer->setGraph(ui->customplot->graph(0)); valleyTracer->setGraphKey(xValue); valleyTracer->setStyle(QCPItemTracer::tsCircle); valleyTracer->setPen(QPen(Qt::green)); valleyTracer->setBrush(Qt::green); valleyTracer->setSize(8); } // 标记过零点 for (int zeroIndex : zeroCrossings) { double xValue = x[zeroIndex]; double yValue = 0; QCPItemTracer *zeroTracer = new QCPItemTracer(ui->customplot); zeroTracer->setGraph(ui->customplot->graph(0)); zeroTracer->setGraphKey(xValue); zeroTracer->setStyle(QCPItemTracer::tsCircle); zeroTracer->setPen(QPen(Qt::blue)); zeroTracer->setBrush(Qt::blue); zeroTracer->setSize(8); } } MainWindow::~MainWindow() { delete ui; } void MainWindow::onCursorModeToggled(bool checked) { cursorEditMode = checked; if (cursorEditMode) { // 进入光标模式,禁用缩放和拖动 ui->customplot->setInteractions(QCP::iSelectPlottables); ui->statusbar->showMessage("光标编辑模式已开启 - 左键添加/移动垂直光标,右键添加/移动水平光标"); cursorModeAction->setIcon(QIcon(":/images/line_icon/rewind-button.png")); ui->measurementModeComboBox->setVisible(true); // 重置测量模式状态 if (ui->measurementModeComboBox->count() > 0) { ui->measurementModeComboBox->setCurrentIndex(0); currentMeasurementMode = NoMeasurement; // 隐藏所有光标和标签 verticalLine1->setVisible(false); verticalLine2->setVisible(false); horizontalLine1->setVisible(false); verticalLabel1->setVisible(false); horizontalLabel1->setVisible(false); verticalLabel2->setVisible(false); horizontalLabel2->setVisible(false); diffLabel->setVisible(false); maxLabel->setVisible(false); minLabel->setVisible(false); verticalLine1Created = false; horizontalLine1Created = false; verticalLine2Created = false; horizontalLine2Created = false; } } else { // 退出光标模式,恢复缩放和拖动 ui->customplot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); ui->statusbar->showMessage("光标编辑模式已关闭"); cursorModeAction->setIcon(QIcon(":/images/line_icon_set_text/rewind-button.png")); // 隐藏所有光标和标签 verticalLine1->setVisible(false); verticalLine2->setVisible(false); horizontalLine1->setVisible(false); verticalLabel1->setVisible(false); horizontalLabel1->setVisible(false); verticalLabel2->setVisible(false); horizontalLabel2->setVisible(false); diffLabel->setVisible(false); maxLabel->setVisible(false); minLabel->setVisible(false); verticalLine1Created = false; horizontalLine1Created = false; verticalLine2Created = false; horizontalLine2Created = false; ui->measurementModeComboBox->setVisible(false); } ui->customplot->replot(); } void MainWindow::onMeasurementModeChanged(int index) { qDebug() << "onMeasurementModeChanged called with index:" << index; // 根据选择的测量模式进行相应的处理 if (ui->measurementModeComboBox->currentText() == "电压测量") { qDebug() << "Switching to Voltage Measurement mode"; currentMeasurementMode = VoltageMeasurement; ui->CursorModelabel->setText("电压测量模式"); // 隐藏垂直光标和标签 verticalLine1->setVisible(false); verticalLine2->setVisible(false); verticalLabel1->setVisible(false); verticalLabel2->setVisible(false); // 显示水平光标和标签 horizontalLine1->setVisible(true); horizontalLine2->setVisible(true); horizontalLabel1->setVisible(true); horizontalLabel2->setVisible(true); // 重置状态 verticalLine1Created = false; verticalLine2Created = false; horizontalLine1Created = false; horizontalLine2Created = false; } else if (ui->measurementModeComboBox->currentText() == "时间测量") { qDebug() << "Switching to Time Measurement mode"; currentMeasurementMode = TimeMeasurement; ui->CursorModelabel->setText("时间测量模式"); // 隐藏水平光标和标签 horizontalLine1->setVisible(false); horizontalLine2->setVisible(false); horizontalLabel1->setVisible(false); horizontalLabel2->setVisible(false); // 显示垂直光标和标签 verticalLine1->setVisible(true); verticalLine2->setVisible(true); verticalLabel1->setVisible(true); verticalLabel2->setVisible(true); // 重置状态 verticalLine1Created = false; verticalLine2Created = false; horizontalLine1Created = false; horizontalLine2Created = false; // 确保垂直光标有正确的初始位置 double xCenter = (ui->customplot->xAxis->range().lower + ui->customplot->xAxis->range().upper) / 2; setupVerticalCursor(verticalLine1, verticalLabel1, xCenter - 10); setupVerticalCursor(verticalLine2, verticalLabel2, xCenter + 10); } // 确保光标在顶层 verticalLine1->setLayer("overlay"); verticalLine2->setLayer("overlay"); horizontalLine1->setLayer("overlay"); horizontalLine2->setLayer("overlay"); // ui->customplot->replot(); // 立即重绘 ui->customplot->replot(QCustomPlot::rpImmediateRefresh); } void MainWindow::mousePressEvent(QMouseEvent *event) { if (cursorEditMode && currentMeasurementMode != NoMeasurement) { double x = ui->customplot->xAxis->pixelToCoord(event->x()); double y = ui->customplot->yAxis->pixelToCoord(event->y()); // 重置拖动状态 isVerticalDragging1 = false; isVerticalDragging2 = false; isHorizontalDragging1 = false; isHorizontalDragging2 = false; if (currentMeasurementMode == TimeMeasurement) { // 时间测量模式,处理垂直光标 if (!verticalLine1Created) { setupVerticalCursor(verticalLine1, verticalLabel1, x); verticalLine1Created = true; isVerticalDragging1 = true; } else if (!verticalLine2Created) { setupVerticalCursor(verticalLine2, verticalLabel2, x); verticalLine2Created = true; isVerticalDragging2 = true; } else { double dist1 = qAbs(x - verticalLine1->point1->coords().x()); double dist2 = qAbs(x - verticalLine2->point1->coords().x()); if (dist1 < dist2) { isVerticalDragging1 = true; } else { isVerticalDragging2 = true; } } } else if (currentMeasurementMode == VoltageMeasurement) { // 电压测量模式,处理水平光标 if (!horizontalLine1Created) { setupHorizontalCursor(horizontalLine1, horizontalLabel1, y); horizontalLine1Created = true; isHorizontalDragging1 = true; } else if (!horizontalLine2Created) { setupHorizontalCursor(horizontalLine2, horizontalLabel2, y); horizontalLine2Created = true; isHorizontalDragging2 = true; } else { double dist1 = qAbs(y - horizontalLine1->point1->coords().y()); double dist2 = qAbs(y - horizontalLine2->point1->coords().y()); if (dist1 < dist2) { isHorizontalDragging1 = true; } else { isHorizontalDragging2 = true; } } } ui->customplot->replot(); // 确保每次点击后立即重绘 } QMainWindow::mousePressEvent(event); } void MainWindow::mouseMoveEvent(QMouseEvent *event) { if (cursorEditMode && currentMeasurementMode != NoMeasurement) { double x = ui->customplot->xAxis->pixelToCoord(event->x()); double y = ui->customplot->yAxis->pixelToCoord(event->y()); if (currentMeasurementMode == TimeMeasurement) { // 时间测量模式,更新垂直光标位置 if (isVerticalDragging1) { moveVerticalCursor(verticalLine1, verticalLabel1, x); } if (isVerticalDragging2) { moveVerticalCursor(verticalLine2, verticalLabel2, x); } } else if (currentMeasurementMode == VoltageMeasurement) { // 电压测量模式,更新水平光标位置 if (isHorizontalDragging1) { moveHorizontalCursor(horizontalLine1, horizontalLabel1, y); } if (isHorizontalDragging2) { moveHorizontalCursor(horizontalLine2, horizontalLabel2, y); } } // 更新差值 updateCursorDiffs(); ui->customplot->replot(); } QMainWindow::mouseMoveEvent(event); } void MainWindow::mouseReleaseEvent(QMouseEvent *event) { // 释放拖动状态 isVerticalDragging1 = false; isVerticalDragging2 = false; isHorizontalDragging1 = false; isHorizontalDragging2 = false; QMainWindow::mouseReleaseEvent(event); } void MainWindow::setupVerticalCursor(QCPItemStraightLine *line, QCPItemText *label, double x) { line->point1->setCoords(x, ui->customplot->yAxis->range().lower); line->point2->setCoords(x, ui->customplot->yAxis->range().upper); line->setVisible(true); label->setVisible(true); updateVerticalCursorLabel(label, x); // 更新标签位置和文本 } void MainWindow::moveVerticalCursor(QCPItemStraightLine *line, QCPItemText *label, double x) { line->point1->setCoords(x, ui->customplot->yAxis->range().lower); line->point2->setCoords(x, ui->customplot->yAxis->range().upper); updateVerticalCursorLabel(label, x); } void MainWindow::updateVerticalCursorLabel(QCPItemText *label, double x) { // 标签位置:在光标顶部,X轴位置为光标位置(转换为坐标轴比例),Y轴位置为1(底部) label->position->setCoords( (x - ui->customplot->xAxis->range().lower) / ui->customplot->xAxis->range().size(), 1.0); label->setText(QString("Time: %1").arg(x, 0, 'f', 2)); } void MainWindow::setupHorizontalCursor(QCPItemStraightLine *line, QCPItemText *label, double y) { line->point1->setCoords(ui->customplot->xAxis->range().lower, y); line->point2->setCoords(ui->customplot->xAxis->range().upper, y); line->setVisible(true); label->setVisible(true); updateHorizontalCursorLabel(label, y); // 确保调用正确的更新标签函数 } void MainWindow::moveHorizontalCursor(QCPItemStraightLine *line, QCPItemText *label, double y) { line->point1->setCoords(ui->customplot->xAxis->range().lower, y); line->point2->setCoords(ui->customplot->xAxis->range().upper, y); updateHorizontalCursorLabel(label, y); // 确保调用正确的更新标签函数 } void MainWindow::updateHorizontalCursorLabel(QCPItemText *label, double y) { // 设置标签的位置:X坐标为x轴的最小值(左侧),Y坐标为光标的Y值 label->position->setCoords(ui->customplot->xAxis->range().lower, y); label->setText(QString("Voltage: \n%1").arg(y, 0, 'f', 2)); } void MainWindow::updateCursorDiffs() { double timeDiff = 0.0; double voltageDiff = 0.0; double maxValue = -std::numeric_limits<double>::max(); double minValue = std::numeric_limits<double>::max(); if (currentMeasurementMode == TimeMeasurement) { // 时间测量模式,计算时间差 if (verticalLine1Created && verticalLine2Created) { double t1 = verticalLine1->point1->coords().x(); double t2 = verticalLine2->point1->coords().x(); timeDiff = qAbs(t2 - t1); // 获取数据 QCPGraph *graph = ui->customplot->graph(0); QVector<double> xData, yData; QCPDataContainer<QCPGraphData>::const_iterator it; for (it = graph->data()->constBegin(); it != graph->data()->constEnd(); ++it) { xData.append(it->key); yData.append(it->value); } // 确定光标区间 double startX = qMin(t1, t2); double endX = qMax(t1, t2); // 计算区间内的最大值和最小值 for (int i = 0; i < xData.size(); ++i) { if (xData[i] >= startX && xData[i] <= endX) { if (yData[i] > maxValue) { maxValue = yData[i]; } if (yData[i] < minValue) { minValue = yData[i]; } } } } } else if (currentMeasurementMode == VoltageMeasurement) { // 电压测量模式,计算电压差 if (horizontalLine1Created && horizontalLine2Created) { double v1 = horizontalLine1->point1->coords().y(); double v2 = horizontalLine2->point1->coords().y(); voltageDiff = qAbs(v2 - v1); // 获取数据 QCPGraph *graph = ui->customplot->graph(0); QVector<double> xData, yData; QCPDataContainer<QCPGraphData>::const_iterator it; for (it = graph->data()->constBegin(); it != graph->data()->constEnd(); ++it) { xData.append(it->key); yData.append(it->value); } // 确定光标区间 double startY = qMin(v1, v2); double endY = qMax(v1, v2); // 计算区间内的最大值和最小值 for (int i = 0; i < xData.size(); ++i) { if (yData[i] >= startY && yData[i] <= endY) { if (yData[i] > maxValue) { maxValue = yData[i]; } if (yData[i] < minValue) { minValue = yData[i]; } } } } } // 更新差值标签 diffLabel->setText(QString("ΔT: %1, ΔV: %2").arg(timeDiff, 0, 'f', 3).arg(voltageDiff, 0, 'f', 3)); diffLabel->setVisible((currentMeasurementMode == TimeMeasurement && verticalLine1Created && verticalLine2Created) || (currentMeasurementMode == VoltageMeasurement && horizontalLine1Created && horizontalLine2Created)); // 更新最大值和最小值标签 maxLabel->setText(QString("Max: %1").arg(maxValue, 0, 'f', 3)); maxLabel->setVisible((currentMeasurementMode == TimeMeasurement && verticalLine1Created && verticalLine2Created) || (currentMeasurementMode == VoltageMeasurement && horizontalLine1Created && horizontalLine2Created)); minLabel->setText(QString("Min: %1").arg(minValue, 0, 'f', 3)); minLabel->setVisible((currentMeasurementMode == TimeMeasurement && verticalLine1Created && verticalLine2Created) || (currentMeasurementMode == VoltageMeasurement && horizontalLine1Created && horizontalLine2Created)); } // 查找峰值 QVector<int> MainWindow::findPeaks(const QVector<double>& data) { QVector<int> peaks; for (int i = 1; i < data.size() - 1; ++i) { if (data[i] > data[i - 1] && data[i] > data[i + 1]) { peaks.append(i); } } return peaks; } // 查找谷值 QVector<int> MainWindow::findValleys(const QVector<double>& data) { QVector<int> valleys; for (int i = 1; i < data.size() - 1; ++i) { if (data[i] < data[i - 1] && data[i] < data[i + 1]) { valleys.append(i); } } return valleys; } // 查找过零点 QVector<int> MainWindow::findZeroCrossings(const QVector<double>& data) { QVector<int> zeroCrossings; for (int i = 1; i < data.size(); ++i) { if ((data[i - 1] < 0 && data[i] >= 0) || (data[i - 1] >= 0 && data[i] < 0)) { zeroCrossings.append(i); } } return zeroCrossings; } 基于上述代码,要实现以下功能,点击Qaction动作进入光标模式,再未点击QComboBox,不进入任意测量模式;点击measurementModeComboBox选择电压测量模式,进入电压测量模式,显示两条水平光标,可以使用鼠标左键移动水平光标并有标签显示实时电压值,并显示电压最大值、电压最小值、电压差值;再点击measurementModeComboBox选择时间测量模式,进入时间测量模式,显示两条垂直光标,可以使用鼠标左键移动垂直光标并有标签显示实时时间值。并显示时间差值。
07-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值