活动介绍

void MainWindow::mousePressEvent(QMouseEvent* event)//鼠標設置障礙物起始,終點 { if(event->button()==Qt::LeftButton&&mode==0)//障礙物 { int j=(event->y()-50)/25-1,i=(event->x()-200)/25; _MAP[i][j]=!_MAP[i][j]; update(); },將鼠標點擊變爲框選完整代碼

时间: 2024-03-17 11:40:51 浏览: 92
完整代码如下: ```cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <QMouseEvent> #include <QPainter> const int MAP_WIDTH = 20; const int MAP_HEIGHT = 20; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); setFixedSize(600, 600); setWindowTitle("A* Path Finding"); mode = 0; isSelecting = false; memset(_MAP, 0, sizeof(_MAP)); } MainWindow::~MainWindow() { delete ui; } void MainWindow::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton && mode == 0) { int j = (event->y() - 50) / 25 - 1; int i = (event->x() - 200) / 25; // 判断鼠标是否在地图区域内 if (i >= 0 && i < MAP_WIDTH && j >= 0 && j < MAP_HEIGHT) { // 记录下鼠标的起点,并将 isSelecting 标记为 true startPoint = endPoint = QPoint(i, j); isSelecting = true; update(); } } } void MainWindow::mouseMoveEvent(QMouseEvent* event) { if (isSelecting) { int j = (event->y() - 50) / 25 - 1; int i = (event->x() - 200) / 25; // 判断鼠标是否在地图区域内 if (i >= 0 && i < MAP_WIDTH && j >= 0 && j < MAP_HEIGHT) { // 记录下鼠标的终点,并调用 update 函数进行界面更新 endPoint = QPoint(i, j); update(); } } } void MainWindow::mouseReleaseEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton && mode == 0 && isSelecting) { // 标记为框选结束 isSelecting = false; // 获取框选的矩形 int left = qMin(startPoint.x(), endPoint.x()); int top = qMin(startPoint.y(), endPoint.y()); int right = qMax(startPoint.x(), endPoint.x()); int bottom = qMax(startPoint.y(), endPoint.y()); // 将框选的矩形内的格子设置为障碍物 for (int i = left; i <= right; i++) { for (int j = top; j <= bottom; j++) { if (i >= 0 && i < MAP_WIDTH && j >= 0 && j < MAP_HEIGHT) { _MAP[i][j] = true; } } } update(); } } void MainWindow::paintEvent(QPaintEvent* event) { QPainter painter(this); // 绘制地图 painter.setPen(Qt::black); painter.setBrush(Qt::white); for (int i = 0; i < MAP_WIDTH; i++) { for (int j = 0; j < MAP_HEIGHT; j++) { if (_MAP[i][j]) { painter.fillRect(QRect(i * 25 + 200, j * 25 + 50, 25, 25), Qt::black); } else { painter.drawRect(QRect(i * 25 + 200, j * 25 + 50, 25, 25)); } } } // 绘制框选的矩形 if (isSelecting) { painter.setPen(Qt::red); painter.setBrush(Qt::NoBrush); painter.drawRect(QRect(startPoint, endPoint)); } } ``` 这个代码实现了在地图上鼠标框选多个格子,并将其设置为障碍物的功能。你可以在窗口中按下鼠标左键并拖动鼠标来进行框选。
阅读全文

相关推荐

#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中实现双光标测量两点之间的差值

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "qcustomplot.h" // 引入QCustomPlot头文件 #include <QWheelEvent> // 引入QWheelEvent头文件 #include <QMouseEvent> // 引入QMouseEvent头文件 #include <QLCDNumber> // 引入 QLCDNumber #include <QFile> // 引入文件操作头文件 #include <QTextStream> // 引入文本流头文件 //添加串口所用的部件 #include <QSerialPort> #include <QString> #include <QSerialPortInfo> #include <QMessageBox> #include <QTimer> #include <QPainter> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); QSerialPort *serialPort;//定义串口指针 private slots: /*手动连接槽函数*/ void manual_serialPortReadyRead(); /*以下为mainwindow.ui文件中点击“转到槽”自动生成的函数*/ void on_openBt_clicked(); void on_sendBt_clicked(); void on_clearBt_clicked(); void on_btnClearSend_clicked(); void on_chkTimSend_stateChanged(int arg1); void on_btnSerialCheck_clicked(); void on_saveToCsvBt_clicked(); // 新增保存到 CSV 的槽函数 private: Ui::MainWindow *ui; // 发送、接收字节计数 long sendNum, recvNum; QLabel *lblSendNum; QLabel *lblRecvNum; QLabel *lblPortState; void setNumOnLabel(QLabel *lbl, QString strS, long num); // 定时发送-定时器 QTimer *timSend; QCustomPlot *customPlot; // 添加QCustomPlot指针 QTimer *dataTimer; // 定时器 QVector<double> xData, yData1, yData2; // 数据存储 QLCDNumber *lcdNumber1; // 添加 QLCDNumber 指针 QLCDNumber *lcdNumber2; // 添加 QLCDNumber 指针 QLCDNumber *lcdNumber3; // 添加 QLCDNumber 指针 void updatePlot(); // 更新图表的函数 void wheelEvent(QWheelEvent *event) override; // 确保加上 override void mousePressEvent(QMouseEvent *event) override; // 鼠标按下事件 void mouseMoveEvent(QMouseEvent *event) override; // 鼠标移动事件 void mouseReleaseEvent(QMouseEvent *event) override; // 鼠标释放事件 bool dragging = false; // 是否正在拖动 QPoint lastMousePos; // 记录鼠标位置 QVector<QByteArray> serialData; // 保存串口数据 void saveDataToCsv(); // 保存数据到 CSV 的函数 }; #endif // MAINWINDOW_H补全这个代码的不足之处

#pragma once #include <QLabel> #include <QWheelEvent> #include <HalconCpp.h> using namespace Halcon; class CMyLabel : public QLabel { Q_OBJECT public: CMyLabel(QWidget *parent = Q_NULLPTR); ~CMyLabel(); //设置Halcon图像和Halcon窗口句柄,用户响应鼠标事件后实时更新图像 void setHalconWnd(Hobject img, HTuple hHalconID, QLabel *label); //鼠标滚轮缩放事件 void wheelEvent(QWheelEvent *ev); //鼠标按下事件 void mousePressEvent(QMouseEvent *ev); //鼠标释放事件 void mouseReleaseEvent(QMouseEvent *ev); //鼠标移动事件 void mouseMoveEvent(QMouseEvent *ev); public: HTuple m_labelID; //Qt标签句柄 HTuple m_hHalconID; //Halcon窗口句柄 Hobject m_currentImg; //当前的图像 //主界面显示坐标的标签 QLabel *m_label; //鼠标按下的位置 HTuple m_tMouseDownRow; HTuple m_tMouseDownCol; bool m_bIsMove; //是否移动图像标识 }; #include "CMyLabel.h" //定义单步放大倍率 #define ZOOMRATIO 2.0 CMyLabel::CMyLabel(QWidget *parent) : QLabel(parent) { m_bIsMove = false; } CMyLabel::~CMyLabel() { } //设置Halcon图像和Halcon窗口句柄,用户响应鼠标事件后实时更新图像 void CMyLabel::setHalconWnd(Hobject img, HTuple hHalconID, QLabel *label) { m_hHalconID = hHalconID; m_currentImg = img; m_label = label; } //鼠标滚轮缩放事件,用于缩放图像 void CMyLabel::wheelEvent(QWheelEvent *ev) { double Zoom; //放大或缩小倍率 HTuple mouseRow, mouseCol, Button; HTuple startRowBf, startColBf, endRowBf, endColBf, Ht, Wt, startRowAft, startColAft, endRowAft, endColAft; //滚轮前滑,放大 if (ev->delta() > 0) { Zoom = ZOOMRATIO; } else { Zoom = 1 / ZOOMRATIO; } //获取光标在原图上的位置,注意是原图坐标,不是Label下的坐标 set_check("~give_error"); Herror ret = get_mposition(m_hHalconID, &mouseRow, &mouseCol, &Button); set_check("give_error"); //当光标不在Halcon窗口内时返回,否则会报错 if (ret != H_MSG_TRUE) { return; } //获取原图显示的部分,注意也是原图坐标 get_part(m_hHalconID, &startRowBf, &startColBf, &endRowBf, &endColBf); //缩放前显示的图像宽高 Ht = endRowBf - startRowBf; Wt = endColBf - startColBf; //普通版halcon能处理的图像最大尺寸是32K*32K。如果无限缩小原图像,导致显示的图像超出限制,则会造成程序崩溃 if ((Ht * Wt < 20000 * 20000 || Zoom == ZOOMRATIO)) { //计算缩放后的图像区域 startRowAft = mouseRow - ((mouseRow - startRowBf) / Zoom); startColAft = mouseCol - ((mouseCol - startColBf) / Zoom); endRowAft = startRowAft + (Ht / Zoom); endColAft = startColAft + (Wt / Zoom); //如果放大过大,则返回 if (endRowAft - startRowAft < 2) { return; } if (m_hHalconID != NULL) { //如果有图像,则先清空图像 detach_background_from_window(m_hHalconID); } set_part(m_hHalconID, startRowAft, startColAft, endRowAft, endColAft); attach_background_to_window(m_currentImg, m_hHalconID); } } //鼠标按下事件 void CMyLabel::mousePressEvent(QMouseEvent *ev) { HTuple mouseRow, mouseCol, Button; set_check("~give_error"); Herror ret = get_mposition(m_hHalconID, &mouseRow, &mouseCol, &Button); set_check("give_error"); //当光标不在Halcon窗口内时返回,否则会报错 if (ret != H_MSG_TRUE) { return; } //鼠标按下时的行列坐标 m_tMouseDownRow = mouseRow; m_tMouseDownCol = mouseCol; m_bIsMove = true; } //鼠标释放事件 void CMyLabel::mouseReleaseEvent(QMouseEvent *ev) { m_bIsMove = false; } //鼠标移动事件 void CMyLabel::mouseMoveEvent(QMouseEvent *ev) { HTuple startRowBf, startColBf, endRowBf, endColBf, mouseRow, mouseCol, Button; //获取当前鼠标在原图的位置 set_check("~give_error"); Herror ret= get_mposition(m_hHalconID, &mouseRow, &mouseCol, &Button); set_check("give_error"); //当光标不在Halcon窗口内时返回,否则会报错 if (ret != H_MSG_TRUE) { return; } //鼠标按下并移动时,移动图像,否则只显示坐标 if (m_bIsMove) { //计算移动值 double RowMove = mouseRow[0].D() - m_tMouseDownRow[0].D(); double ColMove = mouseCol[0].D() - m_tMouseDownCol[0].D(); //得到当前的窗口坐标 get_part(m_hHalconID, &startRowBf, &startColBf, &endRowBf, &endColBf); //移动图像 if (m_hHalconID != NULL) { //如果有图像,则先清空图像 detach_background_from_window(m_hHalconID); } set_part(m_hHalconID, startRowBf - RowMove, startColBf - ColMove, endRowBf - RowMove, endColBf - ColMove); attach_background_to_window(m_currentImg, m_hHalconID); } //获取灰度值 HTuple pointGray; set_check("~give_error"); ret = get_grayval(m_currentImg, mouseRow, mouseCol, &pointGray); set_check("give_error"); //当光标不在Halcon窗口内时返回,否则会报错 if (ret != H_MSG_TRUE) { m_label->setText(QString::fromLocal8Bit("X坐标:- Y坐标:- 灰度值:-")); return; } //设置坐标 m_label->setText(QString::fromLocal8Bit("X坐标:%1 Y坐标:%2 灰度值:%3").arg(mouseCol[0].D()).arg(mouseRow[0].D()).arg(pointGray[0].D())); } #pragma once #include <QtWidgets/QWidget> #include "ui_BrowsePic.h" #include <HalconCpp.h> #include <QToolBar> using namespace Halcon; #pragma execution_character_set("utf-8"); class BrowsePic : public QWidget { Q_OBJECT public: BrowsePic(QWidget *parent = Q_NULLPTR); ~BrowsePic(); //初始化 void init(); //打开窗口 void showImg(); //窗体大小改变事件 void resizeEvent(QResizeEvent *ev); public: //显示图像的控件id HTuple m_hLabelID; //QLabel控件句柄 HTuple m_hHalconID; //Halcon显示窗口句柄 //原始图像的尺寸 HTuple m_imgWidth, m_imgHeight; //图片路径列表 HTuple m_imgFiles; //当前图像 Hobject m_hCurrentImg; //当前图像的下标 HTuple index; //是否等比缩放 bool m_bIsEqualScale; //是否居中显示 bool m_bIsShowCenter; //缩放后的图像 Hobject m_hResizedImg; //缩放系数 HTuple m_hvScaledRate; //缩放后图像的大小 HTuple m_scaledHeight, m_scaledWidth; QToolBar *m_toolBar; public slots: //打开图片 void on_btn_openPic_clicked(); //浏览前一张 void on_btn_prePic_clicked(); //浏览后一张 void on_btn_nextPic_clicked(); //恢复图片 void on_btn_resetPic_clicked(); //等比缩放复选框状态改变 void on_checkBox_equalScale_stateChanged(int); //居中显示复选框状态改变 void on_checkBox_showCenter_stateChanged(int); private: Ui::BrowsePicClass ui; }; #include "BrowsePic.h" #include <QFileDialog> #include <QFileInfo> #include <QLabel> BrowsePic::BrowsePic(QWidget *parent) : QWidget(parent) { ui.setupUi(this); //初始化 init(); } BrowsePic::~BrowsePic() { } //初始化 void BrowsePic::init() { //设置halcon的文件路径为utf8,解决中文乱码 set_system("filename_encoding", "utf8"); //生成空图像 gen_empty_obj(&m_hCurrentImg); //获取图像显示控件的句柄 m_hHalconID = NULL; m_hLabelID = (Hlong)ui.label_show->winId(); m_bIsEqualScale = false; m_bIsShowCenter = true; ui.checkBox_equalScale->setChecked(m_bIsEqualScale); ui.checkBox_showCenter->setChecked(m_bIsShowCenter); ui.checkBox_showCenter->setEnabled(false); } //打开窗口 void BrowsePic::showImg() { //判断图像是否为空 Hlong isEqual; Hobject emptyObj; gen_empty_obj(&emptyObj); test_equal_obj(emptyObj, m_hCurrentImg, &isEqual); if (isEqual) { return; } if (m_hHalconID != NULL) { //如果有图像,则先清空图像 detach_background_from_window(m_hHalconID); } else { //打开窗口 open_window(0, 0, ui.label_show->width(), ui.label_show->height(), m_hLabelID, "visible", "", &m_hHalconID); } ui.label_show->setHalconWnd(m_hCurrentImg, m_hHalconID, ui.label_status); get_image_size(m_hCurrentImg, &m_imgWidth, &m_imgHeight); //判断是否等比缩放 if (m_bIsEqualScale) { //获取缩放系数 tuple_min2(1.0 * ui.label_show->width() / m_imgWidth, 1.0 * ui.label_show->height() / m_imgHeight, &m_hvScaledRate); //进行图像缩放 zoom_image_factor(m_hCurrentImg, &m_hResizedImg, m_hvScaledRate, m_hvScaledRate, "constant"); get_image_size(m_hResizedImg, &m_scaledWidth, &m_scaledHeight); set_window_extents(m_hHalconID, 0, 0, m_scaledWidth, m_scaledHeight); if (m_bIsShowCenter) { if (1.0*ui.label_show->width() / m_imgWidth < 1.0*ui.label_show->height() / m_imgHeight) { set_window_extents(m_hHalconID, ui.label_show->height() / 2.0 - m_scaledHeight / 2.0, 0, ui.label_show->width(), m_scaledHeight); } else { set_window_extents(m_hHalconID, 0, ui.label_show->width() / 2.0 - m_scaledWidth / 2.0, m_scaledWidth, ui.label_show->height()); } } } else { set_window_extents(m_hHalconID, 0, 0, ui.label_show->width(), ui.label_show->height()); } set_part(m_hHalconID, 0, 0, m_imgHeight - 1, m_imgWidth - 1); attach_background_to_window(m_hCurrentImg, m_hHalconID); } //窗体大小改变事件 void BrowsePic::resizeEvent(QResizeEvent *ev) { if (m_hHalconID != NULL) { //防止窗口闪烁 set_system("flush_graphic","false"); showImg(); set_system("flush_graphic", "true"); detach_background_from_window(m_hHalconID); attach_background_to_window(m_hCurrentImg, m_hHalconID); } } //打开图片 void BrowsePic::on_btn_openPic_clicked() { //打开选择文件对话框,选择文件 QString qtFilePath = QFileDialog::getOpenFileName(this, "选择图片", "./", "图像文件(*.jpg *.png *.bmp *.tif)"); if (qtFilePath.isEmpty()) { return; } QFileInfo fileInfo(qtFilePath); qtFilePath.replace("/", "\\"); QString hPath = fileInfo.path().replace("/", "\\"); //由halcon算子获取选中的文件夹中的所有文件 list_files(hPath.toStdString().c_str(), HTuple("files").Append("follow_links"), &m_imgFiles); //筛选符合图片格式的文件 tuple_regexp_select(m_imgFiles, HTuple("\\.(jpg|png|bmp|tif)$").Append("ignore_case"), &m_imgFiles); //找到选择的文件 tuple_find(m_imgFiles, qtFilePath.toStdString().c_str(), &index); //读取图像 read_image(&m_hCurrentImg, HTuple(m_imgFiles[index])); showImg(); } //浏览前一张 void BrowsePic::on_btn_prePic_clicked() { if (index.Num()>0&&index[0].I() > 0) { index[0] = index[0].I() - 1; read_image(&m_hCurrentImg, HTuple(m_imgFiles[index])); showImg(); } } //浏览后一张 void BrowsePic::on_btn_nextPic_clicked() { if (index.Num()>0 && index[0].I() < m_imgFiles.Num() - 1) { index[0] = index[0].I() + 1; read_image(&m_hCurrentImg, HTuple(m_imgFiles[index])); showImg(); } } //恢复图片 void BrowsePic::on_btn_resetPic_clicked() { showImg(); } //等比缩放复选框状态改变 void BrowsePic::on_checkBox_equalScale_stateChanged(int state) { ui.checkBox_showCenter->setEnabled(state); m_bIsEqualScale = state; showImg(); } //居中显示复选框状态改变 void BrowsePic::on_checkBox_showCenter_stateChanged(int state) { m_bIsShowCenter = state; showImg(); } 在vs上运行,halcon是20.11版本

from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * class GraphicsView(QGraphicsView): def init(self, parent=None): super(GraphicsView, self).init(parent) self.setDragMode(QGraphicsView.RubberBandDrag) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.origin = event.pos() self.rubberBand = QRubberBand(QRubberBand.Rectangle, self) self.rubberBand.setGeometry(QRect(self.origin, QSize())) self.rubberBand.setStyleSheet("background-color: rgba(255, 0, 0, 50);") self.rubberBand.show() super(GraphicsView, self).mousePressEvent(event) def mouseMoveEvent(self, event): if self.rubberBand.isVisible(): self.rubberBand.setGeometry(QRect(self.origin, event.pos()).normalized()) super(GraphicsView, self).mouseMoveEvent(event) def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self.rubberBand.hide() rect = self.viewport().rect().intersected(self.rubberBand.geometry()) rect_mapped = self.mapToScene(rect).boundingRect() print(rect_mapped) super(GraphicsView, self).mouseReleaseEvent(event) class MainWindow(QMainWindow): def init(self): super().init() self.graphics_view = GraphicsView(self) self.scene = QGraphicsScene(self.graphics_view) self.graphics_view.setScene(self.scene) self.image = QImage("E:/123.bmp") self.pixmap = QPixmap.fromImage(self.image) self.scene.addPixmap(self.pixmap) self.setCentralWidget(self.graphics_view) if name == 'main': import sys app = QApplication(sys.argv) window = MainWindow() window.setGeometry(500, 200, 800, 600) window.show() sys.exit(app.exec_()) 在这个代码上,增加滑动滚轮可根据鼠标位置进行放大缩小

最新推荐

recommend-type

工业自动化领域中步科触摸屏与台达VFD-M变频器通讯实现电机控制功能 - 电机控制

内容概要:本文档详细介绍了使用步科触摸屏和台达VFD-M变频器实现电机控制功能的技术细节。主要内容涵盖所需的硬件配置(如步科T070触摸屏和支持485功能的USB转485转换头),以及具体的功能实现方法,包括正反转控制、点动停止、频率设定、运行频率读取、电流电压和运行状态的监控。此外,还强调了通讯协议的重要性及其具体实施步骤。 适用人群:从事工业自动化领域的工程师和技术人员,特别是那些负责电机控制系统设计和维护的专业人士。 使用场景及目标:适用于需要集成步科触摸屏与台达VFD-M变频器进行电机控制的应用场合,旨在帮助技术人员掌握正确的硬件选型、安装配置及编程技巧,从而确保系统的稳定性和可靠性。 其他说明:文中提到的操作流程和注意事项有助于避免常见的错误并提高工作效率。同时,提供了详细的通讯说明,确保不同设备之间的兼容性和数据传输的准确性。
recommend-type

langchain4j-community-core-1.0.0-beta4.jar中文-英文对照文档.zip

1、压缩文件中包含: 中文-英文对照文档、jar包下载地址、Maven依赖、Gradle依赖、源代码下载地址。 2、使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 3、特殊说明: (1)本文档为人性化翻译,精心制作,请放心使用; (2)只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; (3)不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 4、温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件。 5、本文件关键字: jar中文-英文对照文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册。
recommend-type

介电弹性体PID DEA模型的参数配置、控制策略与MatlabSimulink建模研究 实战版

内容概要:本文详细探讨了介电弹性体(DEA)PID控制模型的参数配置、控制策略及其在Matlab/Simulink环境中的建模方法。首先介绍了DEA的基本特性如迟滞和非线性响应,并给出了具体的机械系统参数(如刚度、质量和阻尼)。接着讨论了PID控制器的设计,包括基础的位置式PID实现以及针对实际应用需要加入的抗饱和和滤波措施。对于存在输入延迟的情况,提出了使用Smith预估器的方法,并指出其对模型精度的要求。面对突加负载等扰动,推荐采用串级控制提高系统的稳定性。最后强调了利用Automated PID Tuning工具进行参数调整时应注意的问题。 适合人群:从事智能材料控制系统研究的科研人员和技术开发者。 使用场景及目标:适用于希望深入了解并优化介电弹性体驱动器性能的研究者,在理论学习的基础上掌握具体的操作技能,从而更好地应对实际工程中的挑战。 其他说明:文中提供了详细的MATLAB代码片段用于指导读者构建自己的DEA控制模型,同时分享了许多实践经验,帮助避免常见的错误。
recommend-type

pso_uav.zip

1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
recommend-type

Webdiy.net新闻系统v1.0企业版发布:功能强大、易操作

标题中提到的"Webdiy.net新闻系统 v1.0 企业版"是一个针对企业级应用开发的新闻内容管理系统,是基于.NET框架构建的。从描述中我们可以提炼出以下知识点: 1. **系统特性**: - **易用性**:系统设计简单,方便企业用户快速上手和操作。 - **可定制性**:用户可以轻松修改网站的外观和基本信息,例如网页标题、页面颜色、页眉和页脚等,以符合企业的品牌形象。 2. **数据库支持**: - **Access数据库**:作为轻量级数据库,Access对于小型项目和需要快速部署的场景非常合适。 - **Sql Server数据库**:适用于需要强大数据处理能力和高并发支持的企业级应用。 3. **性能优化**: - 系统针对Access和Sql Server数据库进行了特定的性能优化,意味着它能够提供更为流畅的用户体验和更快的数据响应速度。 4. **编辑器功能**: - **所见即所得编辑器**:类似于Microsoft Word,允许用户进行图文混排编辑,这样的功能对于非技术人员来说非常友好,因为他们可以直观地编辑内容而无需深入了解HTML或CSS代码。 5. **图片管理**: - 新闻系统中包含在线图片上传、浏览和删除的功能,这对于新闻编辑来说是非常必要的,可以快速地为新闻内容添加相关图片,并且方便地进行管理和更新。 6. **内容发布流程**: - **审核机制**:后台发布新闻后,需经过审核才能显示到网站上,这样可以保证发布的内容质量,减少错误和不当信息的传播。 7. **内容排序与类别管理**: - 用户可以按照不同的显示字段对新闻内容进行排序,这样可以突出显示最新或最受欢迎的内容。 - 新闻类别的动态管理及自定义显示顺序,可以灵活地对新闻内容进行分类,方便用户浏览和查找。 8. **前端展示**: - 系统支持Javascript前端页面调用,这允许开发者将系统内容嵌入到其他网页或系统中。 - 支持iframe调用,通过这种HTML元素可以将系统内容嵌入到网页中,实现了内容的跨域展示。 9. **安全性**: - 提供了默认的管理账号和密码(webdiy / webdiy.net),对于企业应用来说,这些默认的凭证需要被替换,以保证系统的安全性。 10. **文件结构**: - 压缩包文件名称为"webdiynetnews",这可能是系统的根目录名称或主要安装文件。 11. **技术栈**: - 系统基于ASP.NET技术构建,这表明它使用.NET框架开发,并且可以利用.NET生态中的各种库和工具来实现功能的扩展和维护。 在实施和部署这样的系统时,企业可能还需要考虑以下方面: - **可扩展性**:随着业务的增长,系统应该能容易地扩展,以支持更多的用户和内容。 - **安全性**:除了更改为安全的管理员凭证外,还需考虑防止SQL注入、XSS攻击等网络安全问题。 - **备份和恢复**:定期备份数据库和内容是很重要的,以防数据丢失或需要恢复到先前的状态。 - **多用户和权限管理**:企业环境可能需要多级用户权限设置,以适应不同的团队和角色。 - **SEO优化**:系统应支持良好的搜索引擎优化实践,以便于内容在搜索引擎中的排名和发现。 - **移动适应性**:由于移动设备的广泛使用,系统应具备良好的响应式设计,以提供良好的移动用户体验。 根据描述,该系统似乎是一个成熟的解决方案,适用于需要快速搭建新闻网站的企业用户,但同时也应该注意定期的维护和更新,以确保系统的稳定性和安全性。
recommend-type

【Windows 11用户的福音】:一步到位解决GX Works2安装问题,让兼容性不再是问题!

# 1. GX Works2简介与Windows 11兼容性问题 ## 简介GX Works2 GX Works2是由三菱电机开发的一款针对其PLC(可编程逻辑控制器)产品的编程和调试软件。该软件以其直观的用户界面和强大的编程功能闻名于工业自动化领域,支持从简单的逻辑控制到复杂的系统集成项目。随着Windows操作系统的迭代升级,尤其是新推
recommend-type

电磁加热双边谐振和单边谐振的区别

<think>我们正在处理关于电磁加热技术中双边谐振与单边谐振的工作原理及区别的问题。 首先,需要明确用户意图是了解这两种谐振方式的区别以及它们的工作原理。 我们将通过以下步骤进行: 1. 调用网络搜索工具,检索关于电磁加热中双边谐振和单边谐振的信息。 2. 整合检索到的内容,按照要求生成回答,包括工作原理和区别,并组织成多个方法或步骤(但避免使用步骤词汇,用换行分隔)。 3. 在回答中,如果有公式或代码,按照指定格式处理。 4. 最后,添加相关问题部分。 注意:避免使用第一人称,避免步骤词汇,引用内容不集中末尾,而是融入回答中。 根据搜索,电磁加热中的谐振通常指的是感应加
recommend-type

EnvMan源代码压缩包内容及功能解析

根据给定文件信息,我们需要生成关于“EnvMan-source.zip”这一压缩包的知识点。首先,由于提供的信息有限,我们无法直接得知EnvMan-source.zip的具体内容和功能,但可以通过标题、描述和标签中的信息进行推断。文件名称列表只有一个“EnvMan”,这暗示了压缩包可能包含一个名为EnvMan的软件或项目源代码。以下是一些可能的知识点: ### EnvMan软件/项目概览 EnvMan可能是一个用于环境管理的工具或框架,其源代码被打包并以“EnvMan-source.zip”的形式进行分发。通常,环境管理相关的软件用于构建、配置、管理和维护应用程序的运行时环境,这可能包括各种操作系统、服务器、中间件、数据库等组件的安装、配置和版本控制。 ### 源代码文件说明 由于只有一个名称“EnvMan”出现在文件列表中,我们可以推测这个压缩包可能只包含一个与EnvMan相关的源代码文件夹。源代码文件夹可能包含以下几个部分: - **项目结构**:展示EnvMan项目的基本目录结构,通常包括源代码文件(.c, .cpp, .java等)、头文件(.h, .hpp等)、资源文件(图片、配置文件等)、文档(说明文件、开发者指南等)、构建脚本(Makefile, build.gradle等)。 - **开发文档**:可能包含README文件、开发者指南或者项目wiki,用于说明EnvMan的功能、安装、配置、使用方法以及可能的API说明或开发者贡献指南。 - **版本信息**:在描述中提到了版本号“-1101”,这表明我们所见的源代码包是EnvMan的1101版本。通常版本信息会详细记录在版本控制文件(如ChangeLog或RELEASE_NOTES)中,说明了本次更新包含的新特性、修复的问题、已知的问题等。 ### 压缩包的特点 - **命名规范**:标题、描述和标签中的一致性表明这是一个正式发布的软件包。通常,源代码包的命名会遵循一定的规范,如“项目名称-版本号-类型”,在这里类型是“source”。 - **分发形式**:以.zip格式的压缩包进行分发,是一种常见的软件源代码分发方式。虽然较现代的版本控制系统(如Git、Mercurial)通常支持直接从仓库克隆源代码,但打包成zip文件依然是一种便于存储和传输的手段。 ### 可能的应用场景 - **开发环境配置**:EnvMan可能是用于创建、配置和管理开发环境的工具,这种工具在开发人员设置新的开发机或新的项目环境时非常有用。 - **自动化部署**:EnvMan可能包含自动化部署环境的脚本或命令,使得部署流程变得快捷且高效。 - **监控与维护**:作为环境管理工具,EnvMan可能还支持对环境的监控功能,包括系统资源监控、服务状态检查等,以保证生产环境的稳定性。 ### 总结 尽管以上知识点是基于有限的信息进行的假设性推论,但EnvMan-source.zip包可能是一个用于环境管理的软件或项目的源代码包。该软件或项目可能包含构建和部署自动化环境的能力,以及对运行时环境的监控和维护。文件命名的一致性暗示这是一个正式的版本发布。如果要深入了解EnvMan的功能与用法,建议直接查看压缩包中的文档或源代码注释。同时,考虑到源代码的开发,我们还应该探究该项目所使用的技术栈、编程语言以及版本控制工具等,这将有助于进一步了解EnvMan的技术细节。
recommend-type

【Windows 11终极解决方案】:彻底攻克GX Works2安装中难缠的.Net Framework 3.5障碍!

# 1. Windows 11与GX Works2简介 ## 1.1 Windows 11操作系统概览 Windows 11,作为微软最新的操作系统,不仅仅提供了一种现代的用户体验,而且加强了在企业环境中的安全性与生产力工具。其引入了全新的界面设计、改进的多任务处理以及对Android应用的支持,使它成为IT专业人
recommend-type

贝叶斯gmm

<think>首先,用户的问题是关于贝叶斯高斯混合模型(Bayesian Gaussian Mixture Model, BGMM)的原理和应用。我需要根据系统指令来构建回答。 系统指令包括: - 所有行内数学表达式使用 `$...$` 格式。 - 独立公式使用 `$$...$$` 格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如 `[^1]`。 - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 参考提供的引用: - 引用[1]:讨论了高斯混合模型在机器学习中的应用,包括其优点和挑战。 -