我正在使用VC ++构建Qt应用程序,并且需要带有各种小部件的几种长格式。我试图动态分配这些小部件,以使添加新页面的过程更加简单。
为此,我将QStringList'key'和QVector
到目前为止,我已经在for循环中尝试了以下操作(每个循环都通过一个键):
char typeVal = key[i].toStdString()[0]; // widget type
key[i] = key[i].mid(1); // widget label
switch (typeVal)
{
case 'e': // edit (lineedit)
{
QLineEdit *newEdit = new QLineEdit(page);
connect(newEdit, &QLineEdit::textChanged, [&] {
vec[vecIndex] = newEdit->text().toStdString(); });
layout->addRow(key[i], newEdit);
break;
}
// ...
}
但是,由于newEdit-> text(),这给了我一个“访问冲突读取位置”。这可能与我如何使用lambda函数槽有关,因为我对lambda声明了解不多。如果有此问题的解决方法,或者如果整个过程不必要地复杂,并且有更好的跟踪小部件数据的方法,我希望听到它。
答案 0 :(得分:0)
您报告的访问冲突问题可能有以下原因。
您将信号连接到以下lambda函数:
[&] { vec[vecIndex] = newEdit->text().toStdString(); }
其中[&]
部分告诉编译器通过引用捕获所有变量 ,也就是说,引用绑定到newEdit
变量,该变量随后可在lambda函数中使用身体。但是,这不是您在这种情况下想要的。实际上,对newEdit
的引用已绑定到一个变量,该变量在此绑定之后几乎立即被销毁(也就是说,在您的case
语句范围的末尾),因此稍后尝试读取此变量(在插槽调用时)导致尝试从已破坏的变量中读取内容,因此相应的内存位置可能仅包含任何随机值,甚至根本无法读取。取消引用此类读取操作的结果会导致您报告细分冲突。
您想要的是newEdit
指针的 value (它是QLineEdit
的 pointer ,而不是对象本身),应该被lambda功能插槽保存以备后用。我假设这也适用于vecIndex
,因为它看起来像您在问题中描述的某个循环变量,因此它会更改其值并可能在循环完成后销毁,但这取决于您应用程序的实际上下文。相反,vec
变量可能需要通过引用进行捕获,因为您要修改“全局”矢量,而不是为lambda函数创建的本地副本。
假设,我们来以下lambda函数的声明:
[&vec, vecIndex, newEdit] { vec[vecIndex] = newEdit->text().toStdString(); }
表示以下事实:vec
应该通过引用来捕获,而vecIndex
和newEdit
变量需要通过它们的值来捕获。
希望这会有所帮助。