QCustomPlot Discussion and Comments

click on free space on the plot after selecting item lead to SEGFAULTReturn to overview

When I select an element on the graph, and while it is selected, I click on the empty space on the graph, SEGFAULT occurs.
Here is the call stack:

1  ??                                                                                                    0xfeeefeee 
2  QCustomPlot::processPointSelection                               qcustomplot.cpp                15426 0x42cdac   
3  QCustomPlot::mouseReleaseEvent                                   qcustomplot.cpp                14922 0x42b459   
4  QWidget::event                                                   qwidget.cpp                    8907  0xf0fb0e0  
5  QApplicationPrivate::notify_helper                               qapplication.cpp               3727  0xf0b85ca  
6  QApplication::notify                                             qapplication.cpp               3203  0xf0c0107  
7  QCoreApplication::notifyInternal2                                qcoreapplication.cpp           1048  0x6baf4e01 
8  QCoreApplication::sendSpontaneousEvent                           qcoreapplication.h             237   0xf0bf077  
9  QApplicationPrivate::sendMouseEvent                              qapplication.cpp               2693  0xf0bf077  
10 QWidgetWindow::handleMouseEvent                                  qwidgetwindow.cpp              660   0xf111af4  
11 QWidgetWindow::event                                             qwidgetwindow.cpp              281   0xf113bf9  
12 QApplicationPrivate::notify_helper                               qapplication.cpp               3727  0xf0b85ca  
13 QApplication::notify                                             qapplication.cpp               3099  0xf0bfb83  
14 QCoreApplication::notifyInternal2                                qcoreapplication.cpp           1048  0x6baf4e01 
15 QCoreApplication::sendSpontaneousEvent                           qcoreapplication.h             237   0x185acae  
16 QGuiApplicationPrivate::processMouseEvent                        qguiapplication.cpp            2081  0x185acae  
17 QGuiApplicationPrivate::processWindowSystemEvent                 qguiapplication.cpp            1816  0x185c589  
18 QWindowSystemInterface::sendWindowSystemEvents                   qwindowsysteminterface.cpp     1032  0x183df99  
19 QWindowsGuiEventDispatcher::sendPostedEvents                     qwindowsguieventdispatcher.cpp 82    0x1aecdcb4 
20 qt_internal_proc(HWND__ *, unsigned int, unsigned int, long) *16 qeventdispatcher_win.cpp       237   0x6bb450d1 
21 USER32!AddClipboardFormatListener                                                                     0x7664be6b 
22 USER32!DispatchMessageW                                                                               0x7664833a 
23 USER32!DispatchMessageW                                                                               0x76647bee 
24 USER32!DispatchMessageW                                                                               0x766479d0 
25 QEventDispatcherWin32::processEvents                             qeventdispatcher_win.cpp       629   0x6bb4482c 
26 QWindowsGuiEventDispatcher::processEvents                        qwindowsguieventdispatcher.cpp 74    0x1aecdc87 
27 QEventLoop::processEvents                                        qeventloop.cpp                 136   0x6baf34b0 
28 QEventLoop::exec                                                 qeventloop.cpp                 214   0x6baf3908 
29 QCoreApplication::exec                                           qcoreapplication.cpp           1336  0x6bafbff6 
30 QGuiApplication::exec                                            qguiapplication.cpp            1761  0x18515c6  
31 QApplication::exec                                               qapplication.cpp               2901  0xf0b84a9  
32 qMain                                                            main.cpp                       17    0x4016bb   
33 WinMain *16                                                      qtmain_win.cpp                 104   0x47d6e5   
34 main                                                                                                  0x4df0bd   

Here is the place where the error occurs:
void QCustomPlot::processPointSelection(QMouseEvent *event)
{
  QVariant details;
  QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details);
  bool selectionStateChanged = false;
  bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier);
  // deselect all other layerables if not additive selection:
  if (!additive)
  {
    foreach (QCPLayer *layer, mLayers)
    {
      foreach (QCPLayerable *layerable, layer->children())
      {



      "PROBLEM IS HERE ->" if (layerable != clickedLayerable && mInteractions.testFlag(layerable->selectionCategory()))
        {
          bool selChanged = false;
          layerable->deselectEvent(&selChanged);
          selectionStateChanged |= selChanged;
        }
      }
    }
  }

Here is my code that configures plot window (in case it causes the problem):

void PTS::configureCanvas(QCustomPlot *customPlot)
{
    // add two new graphs and set their look:
    customPlot->addGraph();
    customPlot->addGraph();
    customPlot->graph(0)->setVisible(false);
    customPlot->graph(1)->setVisible(false);
    bars.clear();
    bars.push_back(new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis));
    bars.at(0)->setWidth(1);
    bars.at(0)->setPen(Qt::NoPen);
    bars.at(0)->setBrush(QColor(248, 23, 62, 128));
    bars.at(0)->setSelectable(QCP::stMultipleDataRanges);

    bars.push_back(new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis));
    bars.at(1)->setWidth(1);
    bars.at(1)->setPen(Qt::NoPen);
    bars.at(1)->setBrush(QColor(153, 153, 255, 128));

    bars.push_back(new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis));
    bars.at(2)->setWidth(1);
    bars.at(2)->setPen(Qt::NoPen);
    bars.at(2)->setBrush(QColor(153, 153, 153, 75));
    customPlot->addLayer("belowmain", customPlot->layer("main"), QCustomPlot::limBelow);
    bars.at(2)->setLayer("belowmain");
    // configure right and top axis to show ticks but no labels:
    // (see QCPAxisRect::setupFullAxesBox for a quicker method to do this)
    customPlot->xAxis2->setVisible(true);
    customPlot->xAxis2->setTickLabels(false);
    customPlot->yAxis2->setVisible(true);
    customPlot->yAxis2->setTickLabels(false);
    // make left and bottom axes always transfer their ranges to right and top axes:
    connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis2, SLOT(setRange(QCPRange)));
    connect(customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->yAxis2, SLOT(setRange(QCPRange)));
    // Note: we could have also just called customPlot->rescaleAxes(); instead
    // Allow user to drag axis ranges with mouse, zoom with mouse wheel and select graphs by clicking:
    customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables | QCP::iMultiSelect);
    // let the ranges scale themselves so graph 0 fits perfectly in the visible area:
    customPlot->rescaleAxes();
    connect(bars.at(0),SIGNAL(selectionChanged(const QCPDataSelection&)),\
            this,SLOT(setTracers(const QCPDataSelection&)));
    connect(customPlot, SIGNAL(beforeReplot()),this,SLOT(preventNegative()));
}

The fact is that I don’t want to interfere with qcustomplot code to put a catch for exceptions, but in my part of the program, judging by the call stack, it simply has nowhere to put it.

It seems I have localized the problem. In the setTrabels slot, I remove tracers and labels by removing them from the customplot, and everything works fine if something else is added, but it breaks when I reset the selection.

void PTS::setTracers(const QCPDataSelection& selection)
{
    for(auto curEl : trabels)
    {
        delete curEl.first;
        delete curEl.second;
    }
    trabels.clear();
    for(auto curEl : selection.dataRanges())
    {
        for(int i = curEl.begin(); i < curEl.end(); ++i)
        {
            QCPItemTracer* curTracer = new QCPItemTracer(ui->customPlot);
            curTracer->setGraphKey(static_cast<double>(i));
            curTracer->setStyle(QCPItemTracer::tsNone);
            curTracer->setGraph(ui->customPlot->graph(0));
            QCPItemText* curLabel = new QCPItemText (ui->customPlot);
            curLabel->position->setParentAnchor(curTracer->position);
            curLabel->position->setCoords(0,-LABEL_HEIGHT);
            curLabel->setTextAlignment(Qt::AlignLeft);
            double signal = this->signal.at(i);
            double noise  = midNoise.at(curEl.begin());
            QString sigStr = QString::number(signal);
            QString noiStr = QString::number(noise);
            QString SNR = QString::number(signal/noise).left(sigStr.length());
            QString text = "S  : " + sigStr + "\n" +\
                           "N  : " + noiStr + "\n" +\
                           "SNR: " + SNR;
            QFont courier = QFont("Courier New");
            curLabel->setText(text);
            curLabel->setFont(courier);
            curLabel->setBrush(QColor(255, 255, 255, 128));
            curLabel->setPen(Qt::SolidLine);
            trabels.push_back(QPair<QCPItemTracer*,QCPItemText*>(curTracer,curLabel));
        }
    }
}

Created workaround:
Replaced begin of the setTracers slot with

for(auto curEl : trabels)
    {
        if(selection.dataRanges().length() == 0)
        {
            curEl.second->setVisible(false);
        }
        else
        {
            ui->customPlot->removeItem(curEl.first);
            ui->customPlot->removeItem(curEl.second);
            trabels.clear();
        }
    }