2015-11-05 103 views
0

我試圖通過傳遞一個lambda函數作爲第三個參數來調用QObject::connect作爲QObject的第三個參數傳遞一個lambda函數時出錯:: connect

不過,我視覺的Visual Studio給了我以下錯誤:

Unhandled exception at 0x0000000066B48265 (Qt5Cored.dll) in QCustomPlotInVS_FirstTry.exe: 0xC0000005: Access violation reading location 0x0000000000000008.

這裏是關於調用堆棧的頂部3線時出現錯誤:

Qt5Cored.dll!QListData::size() Line 91
QCustomPlotInVS_FirstTry.exe!QList::size() Line 132 QCustomPlotInVS_FirstTry.exe!QCustomPlot::graph(int index) Line 9657

91號線在QList作。 h是: inline int size() const { return d->end - d->begin; }

我想我得到這個錯誤,因爲我不正確地嘗試使用一個指針(即QCustomPlot* plot)無線一個lambda函數。

我的lambda函數的語法是否正確? 如果不是,我做錯了什麼?

這裏是我稱之爲QObject::connect與lambda函數功能:

void setupRealTimePlot(QCustomPlot* plot, QTimer* dataTimer) 
{ 
    plot->addGraph(); // blue line 
    plot->graph(0)->setPen(QPen(Qt::blue)); 
    plot->graph(0)->setBrush(QBrush(QColor(240, 255, 200))); 
    plot->graph(0)->setAntialiasedFill(false); 
    plot->addGraph(); // red line 
    plot->graph(1)->setPen(QPen(Qt::red)); 
    plot->graph(0)->setChannelFillGraph(plot->graph(1)); 

    plot->addGraph(); // blue dot 
    plot->graph(2)->setPen(QPen(Qt::blue)); 
    plot->graph(2)->setLineStyle(QCPGraph::lsNone); 
    plot->graph(2)->setScatterStyle(QCPScatterStyle::ssDisc); 
    plot->addGraph(); // red dot 
    plot->graph(3)->setPen(QPen(Qt::red)); 
    plot->graph(3)->setLineStyle(QCPGraph::lsNone); 
    plot->graph(3)->setScatterStyle(QCPScatterStyle::ssDisc); 

    plot->xAxis->setTickLabelType(QCPAxis::ltDateTime); 
    plot->xAxis->setDateTimeFormat("hh:mm:ss"); 
    plot->xAxis->setAutoTickStep(false); 
    plot->xAxis->setTickStep(2); 
    plot->axisRect()->setupFullAxesBox(); 

    // make left and bottom axes transfer their ranges to right and top axes: 
    QObject::connect(plot->xAxis, SIGNAL(rangeChanged(QCPRange)), plot->xAxis2, SLOT(setRange(QCPRange))); 
    QObject::connect(plot->yAxis, SIGNAL(rangeChanged(QCPRange)), plot->yAxis2, SLOT(setRange(QCPRange))); 

    // setup a timer that repeatedly calls MainWindow::realtimeDataSlot: 
    QObject::connect(dataTimer, &QTimer::timeout, 
     [&]() 
     { 
      // calculate two new data points: 
      double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0; 
      static double lastPointKey = 0; 
      if (key-lastPointKey > 0.01) // at most add point every 10 ms 
      { 
      double value0 = qSin(key); //qSin(key*1.6+qCos(key*1.7)*2)*10 + qSin(key*1.2+0.56)*20 + 26; 
      double value1 = qCos(key); //qSin(key*1.3+qCos(key*1.2)*1.2)*7 + qSin(key*0.9+0.26)*24 + 26; 
      // add data to lines: 
      plot->graph(0)->addData(key, value0); 
      plot->graph(1)->addData(key, value1); 
      // set data of dots: 
      plot->graph(2)->clearData(); 
      plot->graph(2)->addData(key, value0); 
      plot->graph(3)->clearData(); 
      plot->graph(3)->addData(key, value1); 
      // remove data of lines that's outside visible range: 
      plot->graph(0)->removeDataBefore(key-8); 
      plot->graph(1)->removeDataBefore(key-8); 
      // rescale value (vertical) axis to fit the current data: 
      plot->graph(0)->rescaleValueAxis(); 
      plot->graph(1)->rescaleValueAxis(true); 
      lastPointKey = key; 
      } 
      // make key axis range scroll with the data (at a constant range size of 8): 
      plot->xAxis->setRange(key+0.25, 8, Qt::AlignRight); 
      plot->replot(); 

      // calculate frames per second: 
      static double lastFpsKey; 
      static int frameCount; 
      ++frameCount; 
      if (key-lastFpsKey > 2) // average fps over 2 seconds 
      { 
      lastFpsKey = key; 
      frameCount = 0; 
      } 
     }); 

    dataTimer->start(0); // Interval 0 means to refresh as fast as possible 

} 

回答

2

你通過引用捕獲棧上分配的變量(初犯:plot)在將被稱爲closure後來;所有這些東西一旦被調用就會變成垃圾。取而代之的是價值觀。

+0

你的回答是正確的。我將'[&](){// ...}'改爲'[=](){// ...}'並且它工作正常。但是,我不清楚爲什麼。我想如果我通過價值捕獲它會創建一個變量的副本(在我的例子中是'QCustomPlot * plot'),那麼對副本的任何更改都不適用於原始變量。我想我只是意識到我的擔憂是錯誤的,因爲複製一個指針會給出一個新的變量,它仍然指向我想修改的對象。我的解釋看起來是否正確? – user3731622

+1

沒錯。您可以更容易地將引用解析爲指針:通過引用捕獲本地指針變量就像將指針存儲在雙指針內部一樣。當以後你嘗試使用它時,它指向一個不再存在的局部變量。相反,通過值捕獲它就像創建一個指向原始對象的新QCustomPlot *(指針的值是指向對象的地址)。 –

相關問題