You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt QFormLayout::addRow添加新行不显示、addWidget失效问题

问题根因

控件无法显示、后续布局接口失效的核心原因是Qt控件生命周期管理错误:

  • 你在for循环内部定义的QLineEdit fullNameEdit、QLineEdit shortNameEdit是栈上分配的局部变量,生命周期仅存在于单次循环迭代的作用域内
  • 单次循环结束后这两个输入框会立刻被析构销毁,你传给formLayout->addRow()的是已经失效的野指针,布局拿不到有效控件自然不会渲染任何可见内容
  • 失效的野指针会破坏布局内部的对象树结构,直接导致后续调用addWidget()等接口也无法正常添加控件
修复方案

将需要添加到布局的QLineEdit改为堆上分配(使用new创建),指定父对象即可,Qt的对象树机制会自动管理内存,不需要手动释放。
修复后的循环代码如下:

//Correctly add QLineEdits to the FormLayout
for (auto names : boost::combine(keglerFullName, keglerShortName))  {
    // 改为new创建堆上对象,指定父窗口为keglerTab
    QLineEdit* fullNameEdit = new QLineEdit(ui.keglerTab);
    QLineEdit* shortNameEdit = new QLineEdit(ui.keglerTab);
    QJsonValue fullNameValue, shortNameValue;

    boost::tie(fullNameValue, shortNameValue) = names;
    
    if (fullNameValue.isString()) {
        fullNameEdit->setText(fullNameValue.toString());
        fullNameEdit->setObjectName("fullName");
        fullNameEdit->setMinimumWidth(width);
    }
    if (shortNameValue.isString()) {
        shortNameEdit->setText(shortNameValue.toString());
        shortNameEdit->setMaximumWidth(width);
        shortNameEdit->setObjectName("shortName");
    }

    formLayout->addRow(fullNameEdit, shortNameEdit);
}
额外注意事项
  • 所有需要长期显示的QWidget子类控件都必须在堆上创建,不要将栈上局部控件的指针传给布局,Qt布局不会延长栈对象的生命周期
  • 如果后续需要读取这些输入框的内容,可以给每个输入框设置唯一的objectName,通过父控件的findChild<QLineEdit>()方法查找,也可以提前用QList等容器存储所有输入框的指针方便后续访问

内容的提问来源于stack exchange,提问作者Bugsia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 15:36:28