QCustomPlot鼠标拖拽游标

我在y轴上添加了一个游标,想要通过鼠标来拖动游标在y轴上滑动

要实现在QCustomPlot上拖拽游标,可以这样做:

  1. 定义游标类,继承QGraphicsItem
 cpp
 class Cursor : public QGraphicsItem
 {
 public:
     Cursor();
     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
 }; 
  1. 重写sceneEvent方法,检测鼠标按下和移动事件
 cpp
 void Cursor::sceneEvent(QEvent *event)
 {
     switch (event->type()) {
     case QEvent::GraphicsSceneMousePress:
         mousePressPosition = static_cast<QGraphicsSceneMouseEvent*>(event)->pos();
         break;
     case QEvent::GraphicsSceneMouseMove: 
         if (static_cast<QGraphicsSceneMouseEvent*>(event)->buttons() & Qt::LeftButton) {
            // 拖动游标
            QPointF position = static_cast<QGraphicsSceneMouseEvent*>(event)->pos();
            setPos(mapToParent(position - mousePressPosition)); 
         }
         break;
     }
     QGraphicsItem::sceneEvent(event);
 }
  1. 重写mouseReleaseEvent结束拖拽
 cpp
 void Cursor::sceneEvent(QEvent *event) 
 {
     if (event->type() == QEvent::GraphicsSceneMouseRelease) {
         // 结束拖拽
         mousePressPosition = QPointF(); 
     }
 }

  1. 将游标添加到QCustomPlot的scene中
 cpp
 Cursor *cursor = new Cursor;
 customPlot->scene()->addItem(cursor);

  1. 重写QCustomPlot的mousePressEvent/MoveEvent/ReleaseEvent,转发给游标
 cpp
 void QCustomPlot::mousePressEvent(QMouseEvent *event)
 {
     if (cursor)
         cursor->sceneEvent(event);
     QCustomPlot::mousePressEvent(event);
 }
 
 void QCustomPlot::mouseMoveEvent(QMouseEvent *event) 
 {
     if (cursor)
         cursor->sceneEvent(event);
     QCustomPlot::mouseMoveEvent(event);
 }
 
 void QCustomPlot::mouseReleaseEvent(QMouseEvent *event)
 {
     if (cursor) 
         cursor->sceneEvent(event);
     QCustomPlot::mouseReleaseEvent(event);
 }

这样,当用户在QCustomPlot上单击并拖动鼠标时,会触发游标的sceneEvent方法,从而实现游标的拖拽效果。

希望这个示例能帮助您实现QCustomPlot上拖拽游标的需求。如有任何其他问题,欢迎在评论中提出。

引用chatGPT作答,你可以使用QCustomPlot提供的QCPItemTracer类来实现在y轴上拖拽游标。以下是实现的步骤:

1.创建一个QCPItemTracer对象并将其添加到图表中的y轴上,代码如下:

QCPItemTracer *tracer = new QCPItemTracer(customPlot);
customPlot->addItem(tracer);
tracer->setGraph(customPlot->graph(0)); // 设置关联的图形对象
tracer->setInterpolating(true); // 开启插值模式
tracer->setStyle(QCPItemTracer::tsCircle); // 设置游标的形状
tracer->setPen(QPen(Qt::red)); // 设置游标的边框颜色
tracer->setBrush(Qt::red); // 设置游标的填充颜色
tracer->setGraphKey(xValue); // 设置游标的横坐标位置
tracer->setGraphValue(yValue); // 设置游标的纵坐标位置

2.在QCustomPlot的mouseMoveEvent和mousePressEvent事件中,获取鼠标的纵坐标值,并将其设置为QCPItemTracer对象的纵坐标值,以实现在y轴上拖拽游标。具体代码如下:

void YourWidget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        double mouseY = customPlot->yAxis->pixelToCoord(event->pos().y());
        tracer->setGraphValue(mouseY);
        customPlot->replot();
        event->accept();
    }
}

void YourWidget::mouseMoveEvent(QMouseEvent *event)
{
    double mouseY = customPlot->yAxis->pixelToCoord(event->pos().y());
    tracer->setGraphValue(mouseY);
    customPlot->replot();
    event->accept();
}

在代码中,QCustomPlot的yAxis->pixelToCoord()方法可以将鼠标在y轴上的像素坐标转换为实际的坐标值。tracer->setGraphValue()方法则将转换后的坐标值设置为QCPItemTracer对象的纵坐标位置。最后,调用customPlot->replot()方法来重新绘制图表即可。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
对于QCustomPlot的鼠标拖拽游标操作,可以通过如下的步骤来实现:

1.创建一个QCPItemStraightLine来表示游标,并使用QCustomPlot的addItem方法将其添加到图形界面中。

2.为该直线添加可拖动的事件处理程序。

3.在事件处理函数中,确定新的直线位置,更新直线,并重新绘制QCustomPlot

下面的代码提供一个简单的实现方法,该方法可以在y轴上添加可拖动的游标线:

// 创建一个QCPItemStraightLine对象
QCPItemStraightLine *m_cursorLine = new QCPItemStraightLine(customPlot);

// 设置起始点和终止点
m_cursorLine->setPen(QPen(Qt::red));
m_cursorLine->point1->setCoords(0, 0.5);
m_cursorLine->point2->setCoords(1, 0.5);

// 设置拖动事件处理程序
m_cursorLine->setSelectable(true);
m_cursorLine->setSelected(true);
m_cursorLine->setMovable(true);
m_cursorLine->setClipToAxisRect(false);
connect(customPlot, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event) {
    if (m_cursorLine->selected() && customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis)) {
        double posY = customPlot->yAxis->pixelToCoord(event->pos().y());
        m_cursorLine->point1->setCoords(0, posY);
        m_cursorLine->point2->setCoords(1, posY);
        customPlot->replot();
    }
});

在上述代码中,我们首先创建了一个QCPItemStraightLine对象,然后设置其起始点和终止点,将它添加到QCustomPlot中。然后,我们将其设置为可拖动,并将其连接到QCustomPlot对象的mouseMove事件处理程序中。在事件处理函数中,我们获取y轴上的新位置,根据这个新位置的更新QCPItemStraightLine对象的位置,并重新绘制QCustomPlot图形界面。

希望这个解答对你有帮助!
如果我的回答解决了您的问题,请采纳!

引用new bing部分回答作答:
要在QCustomPlot中实现拖动游标,您需要以下步骤:

1 在y轴上创建一个游标,可以使用QCPItemStraightLine类实现:

QCPItemStraightLine *cursor = new QCPItemStraightLine(customPlot->yAxis);
cursor->setPen(QPen(Qt::black));
cursor->point1->setCoords(0, 0);
cursor->point2->setCoords(1, 1);


2 为了让游标可以拖动,您需要在QCustomPlot的鼠标事件处理函数中处理拖动事件:

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        // Check if cursor is being clicked on
        QCPItemStraightLine *cursor = qobject_cast<QCPItemStraightLine *>(ui->customPlot->plottable(0));
        if (cursor && cursor->selectTest(event->pos(), false) >= 0)
        {
            // Cursor is being clicked on, start dragging
            m_draggingCursor = true;
            m_cursorDragStart = event->pos();
        }
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if (m_draggingCursor)
    {
        // Calculate the cursor's new position
        double pixelDiff = event->pos().y() - m_cursorDragStart.y();
        double valueDiff = ui->customPlot->yAxis->pixelToCoord(pixelDiff);

        // Set the cursor's new position
        QCPItemStraightLine *cursor = qobject_cast<QCPItemStraightLine *>(ui->customPlot->plottable(0));
        if (cursor)
        {
            double newValue = cursor->point1->coords().y() - valueDiff;
            cursor->point1->setCoords(0, newValue);
            cursor->point2->setCoords(1, newValue);
            ui->customPlot->replot();
        }
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        // Cursor drag has ended
        m_draggingCursor = false;
    }
}


3 在类的成员变量中添加以下变量:在类的成员变量中添加以下变量:

bool m_draggingCursor;
QPoint m_cursorDragStart;

完整代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qcustomplot.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_draggingCursor(false)
{
    ui->setupUi(this);

    // Add a graph to the plot
    ui->customPlot->addGraph();

    // Add a cursor to the plot
    QCPItemStraightLine *cursor = new QCPItemStraightLine(ui->customPlot);
    cursor->setPen(QPen(Qt::red));
    cursor->point1->setCoords(0, 0);
    cursor->point2->setCoords(1, 0);

    // Connect mouse events to plot
    ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
    ui->customPlot->installEventFilter(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        mousePressEvent(mouseEvent);
        return true;
    }
    else if (event->type() == QEvent::MouseMove)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        mouseMoveEvent(mouseEvent);
        return true;
    }
    else if (event->type() == QEvent::MouseButtonRelease)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        mouseReleaseEvent(mouseEvent);
        return true;
    }
    else
    {
        return QObject::eventFilter(obj, event);
    }
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        // Check if cursor is being clicked on
        QCPItemStraightLine *cursor = qobject_cast<QCPItemStraightLine *>(ui->customPlot->plottable(0));
        if (cursor && cursor->selectTest(event->pos(), false) >= 0)
        {
            // Cursor is being clicked on, start dragging
            m_draggingCursor = true;
            m_cursorDragStart = event->pos();
        }
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if (m_draggingCursor)
    {
        // Calculate the cursor's new position
        double pixelDiff = event->pos().y() - m_cursorDragStart.y();
        double valueDiff = ui->customPlot->yAxis->pixelToCoord(pixelDiff);

        // Set the cursor's new position
        QCPItemStraightLine *cursor = qobject_cast<QCPItemStraightLine *>(ui->customPlot->plottable(0));
        if (cursor)
        {
            double newValue = cursor->point1->coords().y() - valueDiff;
            cursor->point1->setCoords(0, newValue);
            cursor->point2->setCoords(1, newValue);
            ui->customPlot->replot();
        }
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        // Cursor drag has ended
        m_draggingCursor = false;
    }
}