将lambda函数作为第三个参数传递给QObject::connect。

时间:2021-01-25 18:49:17

I'm trying to call QObject::connect by passing a lambda function as the 3rd parameter.

我尝试调用QObject::通过传递一个lambda函数作为第三个参数。

However, I Visual Visual Studio gives me the following error:

但是,我Visual Visual Studio给了我以下错误:

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

在QCustomPlotInVS_FirstTry中,在0x0000000066B48265 (qt5cor. dll)中未处理的异常。exe: 0xC0000005:访问冲突读取位置0x0000000000000008。

Here is the top 3 lines on the Call Stack when the error occurs:

这里是当错误发生时调用堆栈上的前3行:

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

size():size():size(), Line - height: 130%; font - family:宋体;mso - ascii - font - family: tahoma;QCustomPlot::图(int指数)第9657行

Line 91 in qList.h is: inline int size() const { return d->end - d->begin; }

在qList 91行。h是:inline int size() const {return d->end - d->开始;}

I think I'm getting this error because I'm incorrectly trying to use a pointer (i.e. the QCustomPlot* plot) with a lambda function.

我想我得到了这个错误,因为我错误地尝试用一个lambda函数来使用指针(也就是QCustomPlot* plot)。

Is my syntax for the lambda function correct? If not, what am I doing wrong?

我的lambda函数的语法正确吗?如果没有,我做错了什么?

Here is the function in which I call the QObject::connect with a lambda function:

这里是我调用QObject的函数::连接一个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

}

1 个解决方案

#1


2  

You are capturing stack-allocated variables by reference (first offender: plot) in a closure that is going to be called later; all that stuff is going to be garbage once your closure is called. Capture by value instead.

您可以通过引用(第一个犯罪者:plot)来捕获堆栈分配的变量,然后在稍后调用该闭包;一旦你的闭包被调用,所有这些东西都会变成垃圾。捕获的价值。

#1


2  

You are capturing stack-allocated variables by reference (first offender: plot) in a closure that is going to be called later; all that stuff is going to be garbage once your closure is called. Capture by value instead.

您可以通过引用(第一个犯罪者:plot)来捕获堆栈分配的变量,然后在稍后调用该闭包;一旦你的闭包被调用,所有这些东西都会变成垃圾。捕获的价值。