QT 5.6 QVBoxLayout removeWidget然后addWidget无法按预期工作 [英] QT 5.6 QVBoxLayout removeWidget then addWidget not working as expected

查看:372
本文介绍了QT 5.6 QVBoxLayout removeWidget然后addWidget无法按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我到处搜索,没有发现任何可以解决此问题的方法.我制作了一个QVBoxLayout,然后进行了网络调用以获取数据.当数据返回时,我向此QVBoxLayout添加4个自定义小部件

I searched everywhere and found nothing that solved this. I make a QVBoxLayout and then make a web call for data. When the data comes back I add 4 custom widgets to this QVBoxLayout

verticalLayout->addWidget(nsd);

对于前四个,效果很好.一切按需出现.但是,我想删除四个小部件中的任何一个,然后在底部添加一个小部件.删除效果很好

For the first four this works great. Everything appears as needed. However, I want to delete any one of the four widgets then add a widget at the bottom. Deleting works fine

 verticalLayout->removeWidget(nsd);
delete nsd;

我知道它可以正常工作,因为那样该小部件将不再显示在我的屏幕上.问题在于添加小部件无法完全正常工作.我叫相同的代码

I know it works fine because then that widget not longer draws to my screen. The problem is that adding the widget is not working entirely. I call the same code

verticalLayout->addWidget(nsd);

并检查verticalLayout-> count()会告诉我有4个项目.该窗口小部件是使用与之前添加的父窗口小部件相同的父窗口小部件创建的.永远不会调用新窗口小部件的paint事件.此外,屏幕上显示的3表示间隔3个项目.并不是任何地方都有洞.我也尝试添加然后删除,但这是相同的问题.新项目永远不会被绘制,其大小也不会被考虑在内.

and checking verticalLayout->count() tells me there are 4 items. The widget is created with the same parent widget as the ones added before. The paint event of the new widget never gets called. Furthermore the 3 that show on the screen show spaced for 3 items. It's not like there's a hole anywhere. I also tried adding then deleting but it's the same problem. The new item never gets drawn and its size never factored in.

推荐答案

如果要完全摆脱小部件,则只需对其进行销毁.您不必担心它是否在布局中.如果窗口小部件是动态分配的,则只需delete nsd,就不需要layout->removeWidget调用.您也不必为窗口小部件提供任何明确的父级-在布局中插入将设置适当的父级.

If you want to get rid of a widget completely, you only need to destruct it. You don't have to worry if it was in a layout. If the widget is dynamically allocated, then delete nsd is all you need, the layout->removeWidget call is not needed. You also don't have to give widgets any explicit parents - insertion into the layout will set proper parent.

无论添加或删除的窗口小部件类型如何,以下内容均有效且安全.如果删除在调用堆栈上具有目标小部件,则应使用deleteLater而不是普通的delete.但是,除非响应目标小部件重新进入事件循环(否则,它不应该),否则您将其删除以响应来自无关小部件的信号而绝不会发生这种情况.

The following works and is safe no matter what is the type of the widget being added/removed. If the deletion had target widget on the call stack, you should use deleteLater instead of plain delete. But this can never be the case when you delete it in response to a signal from an unrelated widget, unless the target widget re-enters the event loop (aargh! it shouldn't).

// https://github.com/KubaO/stackoverflown/tree/master/questions/layout-addremove-37814292
#include <QtWidgets>

int main(int argc, char ** argv) {
   QApplication app(argc, argv);
   QWidget widget;
   QVBoxLayout layout(&widget);
   QPushButton button;
   QLabel label("Hello");
   layout.addWidget(&button);
   layout.addWidget(&label);

   auto onClick = [&]{
      if (layout.count() == 3) {
         delete layout.itemAt(2)->widget();
         button.setText("Add");
      } else {
         layout.addWidget(new QLabel("Hello too!"));
         button.setText("Remove");
      }
   };
   QObject::connect(&button, &QPushButton::clicked, onClick);
   onClick();

   widget.show();
   return app.exec();
}

这篇关于QT 5.6 QVBoxLayout removeWidget然后addWidget无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆