QCustomPlot点击事件无效

使用QCustomPlot做曲线图时,发现点击事件都无效。怎么解决

void QHisCurv::mousePressEvent(QMouseEvent *event)
{
    //movePoint = event->pos();
    ////QPixmap temPixmap = inertPixmap;
    ////QPainter painter(&temPixmap);
    //bDrawMousePresse = true;
    //update();
    ////pixmap = temPixmap;
    ////repaint();
    QMessageBox::information(this,"提示信息","QCustomPlot被点击");
}

可以尝试重写 QCustomPlot 的鼠标点击事件,例如:

class MyCustomPlot : public QCustomPlot
{
public:
    MyCustomPlot(QWidget *parent = nullptr) : QCustomPlot(parent) {}

protected:
    void mousePressEvent(QMouseEvent *event) override
    {
        // 处理鼠标点击事件
        QMessageBox::information(this, "提示信息", "QCustomPlot被点击");
        QCustomPlot::mousePressEvent(event);
    }
};

然后使用 MyCustomPlot 替换原来的 QCustomPlot 即可:

MyCustomPlot *plot = new MyCustomPlot(this);

这样就可以在鼠标点击 QCustomPlot 时弹出提示信息了。

如果还有问题,建议检查一下是否正确连接了信号和槽函数。例如,如果您想在点击曲线时弹出提示信息,可以这样连接信号和槽函数:

connect(plot, &QCustomPlot::plottableClick, [=](QCPAbstractPlottable *plottable, int dataIndex) {
    QMessageBox::information(this, "提示信息", "曲线被点击");
});

这样就可以在点击曲线时弹出提示信息了。

引用chatgpt部分指引作答:
如果你使用QCustomPlot库创建曲线图时发现点击事件无效,可能是因为没有正确设置相应的属性或信号槽连接。以下是一些常见的解决方法:
1.确保QCustomPlot对象的交互属性被启用。你可以在创建QCustomPlot对象后使用setInteractions函数来启用交互属性,例如:

QCustomPlot* customPlot = new QCustomPlot(this);
customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

这将启用拖动、缩放和选择等交互功能。
2.检查是否正确连接了鼠标点击事件的信号槽。在你的代码中,确保你的QHisCurv类已经正确地继承了QWidget,并在构造函数中设置了相应的信号槽连接,例如:


connect(this, SIGNAL(mousePressEvent(QMouseEvent*)), this, SLOT(onMousePressEvent(QMouseEvent*)));

然后,在你的类中实现onMousePressEvent槽函数,处理你想要的点击事件逻辑。
3.如果你希望在QCustomPlot上显示自定义的提示信息,而不是使用QMessageBox,你可以使用QToolTip来显示提示信息。在你的onMousePressEvent槽函数中,使用QToolTip::showText函数来显示信息,例如:

void QHisCurv::onMousePressEvent(QMouseEvent *event)
{
    QToolTip::showText(event->globalPos(), "QCustomPlot被点击", this);
}

希望能帮助到你。

该回答引用GPT与博主@晓码自在合作编写:

这是一个常见的问题。QCustomPlot是一个第三方库,所以默认情况下,它不会发送鼠标点击事件到窗口。要capture鼠标点击事件,需要做以下几步:

  1. 在QCustomPlot中启用鼠标跟踪(mouse tracking)。这可以通过调用setMouseTracking(true)来实现:
cpp
ui->customPlot->setMouseTracking(true);

  1. 实现QCustomPlot的mousePressEvent信号的槽函数,用于捕获鼠标单击事件:
cpp 
connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(onCustomPlotMousePress(QMouseEvent*)));

  1. 实现onCustomPlotMousePress槽函数:
cpp 
void onCustomPlotMousePress(QMouseEvent *event) 
{
    QMessageBox::information(this,"提示信息","QCustomPlot被点击");
}

  1. 在QCustomPlot中的plot layout中启用鼠标点击事件(可点击),例如:
cpp
QCPLayoutGrid *plotLayout = new QCPLayoutGrid;
plotLayout->setMouseClickable(true);  // 启用鼠标点击
ui->customPlot->plotLayout()->addItem(plotLayout);

以上步骤完成后,你的鼠标点击事件就可以正常工作了。一个完整的例子如下:

cpp
#include "qcustomplot.h"
#include <QMessageBox>

void MainWindow::on_customPlot_mousePress(QMouseEvent *event) 
{
    QMessageBox::information(this,"提示信息","QCustomPlot被点击");
}

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent)
{
    ui->setupUi(this);
    ui->customPlot->setMouseTracking(true);

    connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(on_customPlot_mousePress(QMouseEvent*)));

    QCPLayoutGrid *plotLayout = new QCPLayoutGrid;
    plotLayout->setMouseClickable(true);  
    ui->customPlot->plotLayout()->addItem(plotLayout);
}  

希望这能帮助你解决在QCustomPlot中捕获鼠标点击事件的问题。

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/715535
  • 这篇博客也不错, 你可以看下QCustomplot笔记(一)之QCustomplot添加数据以及曲线
  • 除此之外, 这篇博客: QCustomPlot使用之绘制散点图中的 QCustomPlot使用之绘制散点图 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 以下回答由chatgpt基于相关博客总结生成:

    针对点击事件无效的问题,可以按照以下步骤解决:

    1. 定义鼠标点击事件的槽函数,例如:

    ```cpp void MyWidget::mousePressEvent(QMouseEvent* event) { //获取鼠标点击的坐标 double x = qCustomPlot->xAxis->pixelToCoord(event->pos().x()); double y = qCustomPlot->yAxis->pixelToCoord(event->pos().y());

    //在控制台输出坐标信息
    qDebug() << "鼠标点击的坐标为:" << x << "," << y;
    

    } ```

    1. 在构造函数中设置鼠标跟踪:
    MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
    {
        ui.setupUi(this);
        //设置鼠标跟踪
        qCustomPlot->setMouseTracking(true);
    }
    
    1. 在mainwindow.ui中添加一个widget控件,将其提升为QCustomPlot类型,然后在代码中将qCustomPlot指向该控件:
    qCustomPlot = ui->myPlot;
    
    1. 在mainwindow.ui中将QCustomPlot的interaction属性设置为iSelectItems,使其支持选中图形项:

    QCustomPlot_interaction属性设置为iSelectItems.png

    1. 然后在绘图代码中,需要保证绘制的图形项设置了可选中的标记,例如:
    //添加一条曲线
    QCPGraph* graph = qCustomPlot->addGraph();
    //设置曲线数据等
    //...
    //添加可选中的标记
    graph->setSelectable(QCP::stSingleData);
    

    其中,QCP::stSingleData表示该标记在每个数据点上只能选中一个。

    1. 最后,当选中了某个图形项时,会触发selectedPlottables信号,可以连接该信号与一个槽函数来处理选中事件:
    connect(qCustomPlot, SIGNAL(selectedPlottables(QList<QCPAbstractPlottable*>)), this, SLOT(handleSelected(QList<QCPAbstractPlottable*>)));
    
    //槽函数定义如下
    void MyWidget::handleSelected(QList<QCPAbstractPlottable*> plottables)
    {
        //遍历选中的图形项
        foreach(QCPAbstractPlottable* plottable, plottables)
        {
            if(plottable->inherits("QCPGraph"))
            {
                QCPGraph* graph = qobject_cast<QCPGraph*>(plottable);
                //获取选中的数据点
                QVector<QPointF> selectedPoints = graph->selectedDataPoints();
                foreach(QPointF point, selectedPoints)
                {
                    qDebug() << "选中曲线 " << graph->name() << " 的点:(" << point.x() << ", " << point.y() << ")";
                }
            }
        }
    }
    

    这样,就可以在QCustomPlot中实现点击事件的响应了。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
QCustomPlot自身具有处理鼠标事件的机制,如果直接重写QWidget的鼠标事件会导致QCustomPlot内部的鼠标事件失效。

正确的方法是使用QCustomPlot提供的信号和槽机制处理鼠标事件,具体可以通过以下步骤实现:

  1. 在构造函数中连接信号和槽:
    connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(onMousePress(QMouseEvent*)));
    
  2. 在槽函数中处理鼠标事件:
    void QHisCurv::onMousePress(QMouseEvent *event)
    {
     QMessageBox::information(this,"提示信息","QCustomPlot被点击");
    }
    
    其中,ui->customPlot是QCustomPlot对象的指针,onMousePress是处理鼠标事件的槽函数。这样,当QCustomPlot被点击时,onMousePress函数就会被调用。

完整代码如下:

// 在构造函数中连接信号和槽
connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(onMousePress(QMouseEvent*)));

// 处理鼠标点击事件的槽函数
void QHisCurv::onMousePress(QMouseEvent *event)
{
    QMessageBox::information(this,"提示信息","QCustomPlot被点击");
}

如果我的回答解决了您的问题,请采纳!

在QCustomPlot中,要使鼠标事件处理生效,需要确保以下几点:

  1. 确认图表对象已经安装了事件过滤器,如果没有安装,需要手动安装事件过滤器。例如,在窗口的构造函数中添加以下代码:
ui->customPlot->installEventFilter(this);
  1. QCustomPlot必须启用交互模式,才能响应鼠标事件。您可以通过以下方式设置此属性:
ui->customPlot->setInteractions(QCP::iRangeZoom | QCP::iSelectPlottables);
  1. 需要确保子类化的图表控件主窗口的鼠标事件处理函数有效果,并调用到了父类的同名函数。例如在 mousePressEvent 函数处理结束时,必须调用:
QCustomPlot::mousePressEvent(event);

在您提供的代码中,可能您直接将QMessageBox嵌入 mousePressEvent 中,但是这可能会阻塞后面更重要的更新操作。您可以使用 qDebug() 函数或者在独立的槽函数中触发 QMessageBox 的显示。

除此之外,还需要注意的是:部分场景下,您可能需要禁用一些默认的交互动作(如轴缩放),以便正确触发自定义事件。

需要在构造函数中添加以下代码来注册控件:

this->setMouseTracking(true);
this->setAttribute(Qt::WA_AcceptTouchEvents, true);
this->setViewport(new QWidget);

这三句代码是用于设置QCustomPlot控件的属性和特性的。分别说明如下:
this->setMouseTracking(true);
这句代码将控件的鼠标跟踪属性设置为true,即当鼠标移动到控件上时,就会触发MouseMoveEvent事件。这对于绘制图形中的交互操作非常有用,比如在曲线图上绘制一个数据点。
this->setAttribute(Qt::WA_AcceptTouchEvents, true);
这句代码设置控件接受触摸事件。在支持触摸屏的设备上,如果希望能够通过触摸屏对控件进行操作,则需要设置此属性为true。如果不需要触摸支持,则可以省略这句代码。
this->setViewport(new QWidget);
这句代码将控件的viewport设置为一个新的QWidget对象,并将其作为控件的子控件。viewport是指控件的可视区域,该操作将控件的可视区域与子控件进行关联,使得在控件中添加子控件时,只需将这些子控件添加到viewport中即可。

该回答参考ChatGPT:
在QCustomPlot中,通过重写mousePressEvent()函数来处理点击事件。在这个函数中,首先获取鼠标点击位置的坐标,并将该坐标保存在movePoint变量中。接着,通过调用update()函数来更新曲线图的显示,并使用pixmap()函数获取图形的Pixmap对象。最后,调用repaint()函数来重绘曲线图。
在这个函数中,如果想要让点击事件生效,需要重新设置bDrawMousePresse为true。可以通过在QMouseEvent中设置event->setAccepted(true)将其设置为true。这样,在点击事件中就可以处理各种事件了。
另外,如果想要在每次点击时都触发bDrawMousePresse,可以在QCustomPlot中重写mouseMoveEvent()和mousePressEvent()函数,并在每个事件中都调用update()和pixmap()函数。这样就可以在每次点击时都触发bDrawMousePresse。

如果您使用 QCustomPlot 绘制曲线图时发现点击事件无效,可能是因为 QCustomPlot 默认情况下会捕获所有的鼠标事件,导致您自定义的鼠标事件无法被触发。您可以通过设置 QCustomPlot 的交互模式来解决这个问题:

cpp
Copy
ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
在这个示例中,我们调用了 setInteractions 函数,将 QCustomPlot 的交互模式设置为可以拖动、缩放和选择可绘制对象。这样,QCustomPlot 就会将鼠标事件传递给可绘制对象,同时也会触发自定义的鼠标事件。

另外,如果您想要在 QCustomPlot 中显示提示信息,可以使用 QToolTip::showText 函数。例如:

cpp
Copy
QToolTip::showText(event->globalPos(), "QCustomPlot 被点击", this);
在这个示例中,我们在鼠标点击事件中调用了 QToolTip::showText 函数,将提示信息显示在鼠标点击的位置上。需要注意的是,第一个参数传递了鼠标点击事件的全局坐标,第二个参数是要显示的提示文本,第三个参数是要显示提示信息的控件。

可以借鉴下

提示"public: virtual struct QMetaObject const * __cdecl QC... 类似的错误

原因:需要使用QT的编译工具(我使用的QT creator)重新编译,会生成moc_qcustomplot.cpp文件,将该文件添加到VS工程,重新编译



参考ChatGPT部分内容作答:
在使用QCustomPlot绘制曲线图时,需要将QCustomPlot的交互模式设置为QCP::iSelectPlottables,这样才能够响应鼠标点击事件。可以在构造函数中添加如下代码:

QHisCurv::QHisCurv(QWidget *parent) : QWidget(parent)
{
    // ...
    // 设置交互模式为选择可绘制对象
    customPlot->setInteractions(QCP::iSelectPlottables);
    // ...
}

另外,需要确保QCustomPlot的背景不是透明的,否则点击事件也会无效。可以在构造函数中添加如下代码:

QHisCurv::QHisCurv(QWidget *parent) : QWidget(parent)
{
    // ...
    // 设置背景为白色
    customPlot->setBackground(QBrush(Qt::white));
    // ...
}

如果以上方法都无效,可以尝试在QCustomPlot的父控件中重载mousePressEvent函数,并在其中调用QCustomPlot的mousePressEvent函数,例如:

void QParentWidget::mousePressEvent(QMouseEvent *event)
{
    // 调用QCustomPlot的mousePressEvent函数
    customPlot->mousePressEvent(event);
}

答案参考ChatGPT Plus版,整理汇总。希望能帮助你解决问题
在您提供的代码中,鼠标点击事件被注释掉了,并且显示了一个消息框作为替代。如果您希望修复鼠标点击事件并使其有效,请按照以下步骤进行修改:

  1. 解除mousePressEvent函数的注释,恢复原始代码。
void QHisCurv::mousePressEvent(QMouseEvent *event)
{
    // movePoint = event->pos();
    // QPixmap temPixmap = inertPixmap;
    // QPainter painter(&temPixmap);
    // bDrawMousePresse = true;
    // update();
    // pixmap = temPixmap;
    // repaint();
    QMessageBox::information(this, "提示信息", "QCustomPlot被点击");
}
  1. 确保QHisCurv类继承自QCustomPlot,或者将QCustomPlot对象作为QHisCurv类的成员变量。
class QHisCurv : public QCustomPlot
{
    // ...
};
  1. 确保QHisCurv对象被正确地添加到父级窗口或布局中,并具有适当的大小和位置。

  2. 在父级窗口或相关部件的事件处理函数中,将事件传递给QHisCurv对象。例如,如果QHisCurv是作为QWidget的子类,并且位于父级窗口中,可以在父级窗口的事件处理函数中调用QHisCurv::event(event)来传递事件。

void ParentWidget::mousePressEvent(QMouseEvent *event)
{
    QHisCurv::event(event);
}

通过按照上述步骤进行修改,您应该能够修复QCustomPlot的鼠标点击事件,并使其有效。请根据您的实际需求和代码结构进行相应的调整。