我正在使用VC ++构建Qt应用程序,并且需要带有各种小部件的几种长格式。我试图动态分配这些小部件,以使添加新页面的过程更加简单。
为此,我将QStringList'key'和QVector 'vec'传递到保存该窗体的QDialog中。 key [i]的第一个字符保存窗口小部件类型,其余的保留标签。另一方面,每个vec [i]都需要保存用户更改的任何相应信息(来自动态创建的小部件)。
到目前为止,我已经在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声明了解不多。如果有此问题的解决方法,或者不必要地困扰整个过程,并且有更好的跟踪小部件数据的方法,我很想听听。
最佳答案
您报告的访问冲突问题可能有以下原因。
您将信号连接到以下lambda函数:[&] { vec[vecIndex] = newEdit->text().toStdString(); }
其中[&]
部分告诉编译器通过引用捕获所有变量,即,引用绑定到newEdit
变量,该变量随后可在lambda函数体内使用。但是,这不是您在这种情况下想要的。实际上,对newEdit
的引用已绑定到一个变量,该变量几乎在此绑定之后立即被销毁(即,在您的case
语句作用域的末尾),因此请稍后尝试读取此变量(在插槽调用时)时间)导致尝试从已破坏的变量中读取内容,因此相应的内存位置可能只包含任何随机值,甚至根本无法读取。取消引用此类读取操作的结果会导致您报告分段错误。
这里需要的是newEdit
指针的值(它是指向QLineEdit
的指针,而不是对象本身),应保存以供lambda函数插槽以后使用。我想这同样适用于vecIndex
,因为它看起来像您在问题中描述的某个循环变量,因此它会更改其值,并可能在循环完成后被破坏,但这取决于您应用程序的实际上下文。相反,vec
变量可能需要按引用捕获,因为您要修改“全局”矢量,而不是为lambda函数创建的本地副本。
假设,我们来以下lambda函数的声明:[&vec, vecIndex, newEdit] { vec[vecIndex] = newEdit->text().toStdString(); }
这表示了vec
应该通过引用捕获的事实,而vecIndex
和newEdit
变量需要通过它们的值捕获。
希望这可以帮助。