jeudi 29 janvier 2015

Qt crashes when calling nested lambda to change widget

I am working on a project using C++ and QT. Part of the project involves a structure which keeps track of methods to update widgets. I have included a sample program below which highlights the issue, which is the problem distilled.


In the program, I have a list of 'relations', which contains lambdas to change widgets, based on data obtained elsewhere. This works fine (and may be dumped), but the problem is when one lambda is calling another.


An example is below. This program only has a combobox with the three strings, which calls 'slot1()' when changed. Slot one then calls the function pushed into the vector with the row, and calls that function with the parameter.


The Vector is



QVector<std::function<void(int)>> func;


When func.pushback takes setProductIndex as a parameter, the program works (I understand this is essentially a no op). The function is called. When it takes setProductIndex2, the program segfaults when the combobox is changed.


I have verified that the functions are indeed being called, but I'm unsure why it would segfault with setProductIndex2. All that is doing, is calling setProductIndex with the passed value which DOES work.


I can work around this, but I would like to know where I'm going wrong for better understanding.


I'm using GCC v4.8.3 and qt 5.3.2 on Fedora Linux.


Thanks.



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

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
qDebug() << "1";
ui->setupUi(this);
QStringList model;
model.append("Test1");
model.append("Test2");
model.append("Test3");
ui->comboBox->addItems(model);
qDebug() << "2";
std::function<void(int)> setProductIndex = [&] (int x) ->void { ui->comboBox->setCurrentIndex(x);
ui->comboBox->setCurrentIndex(x); return;} ;
std::function<void(int)> setProductIndex2 = [&] (int x) ->void {setProductIndex(x);};
func.push_back(setProductIndex2);
qDebug() << "Func size " << func.size();
}

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

void MainWindow::slot1(int xx)
{

//ui->comboBox->setCurrentIndex(--xx);
func[0](xx);
}

Aucun commentaire:

Enregistrer un commentaire