dar*_*aze 15 layout qt qt4 widget
(我使用Qt 4.7,Windows 7,64bit).
我创建了一个自定义表.每行都是带有小部件的水平布局.行保存在QList中以便于访问,孩子也是如此.这些行也会添加到父窗口小部件中.
如果我调整父窗口小部件的大小,我会计算新的大小,删除所有内容,然后重新创建它.
我的问题是我不想删除任何小部件.只有当我清理桌子时,我才会这样做.
由于我在QList内部和父布局内部有小部件,如何删除每行中的所有小部件,删除所有布局,然后将它们添加到新布局?
如果我这样做:takeAt(0)为每个布局中的每个元素我有一个QLayoutItem,里面有一个小部件...如何在不删除小部件的情况下删除layoutItem?....如何删除小部件而不删除它,无论是父母还是孩子?因为有很多方法可以删除:removeItem,removeWidget ...在布局中,但不是takeWidget ...只是takeAt(),它给出了一个Qlayoutitem.
我尝试了几种方法,但无论发生什么事,我仍然会看到小部件.
关于这个的问题:
小部件何时被删除?如果我从布局中取出窗口小部件(索引),它是否会被删除一段时间?如果我在另一个列表中有一个指针,它会发生吗?
removeAt(index)是否执行widget的delete方法?
dar*_*aze 25
好.我搞定了.让我解释一下如何删除,保持小部件的工作原理.
窗口小部件的父布局已知.然后你通过布局删除它.通过做:
layout()->removeAt(widget);
delete widget;
Run Code Online (Sandbox Code Playgroud)
如果在QLayout(或其子代)中使用takeAt(index),它会为您提供QLayoutItem.要访问里面的小部件,只需使用widget().但是没有删除它就无法移除小部件.所以这种方法无效.
在Docs中,它告诉了一种删除元素的方法:
QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0) {
...
delete child;
}
Run Code Online (Sandbox Code Playgroud)
Qt中要注意的一件特别的事情是这样的:如果你有一个布局的层次树,加入addLayout()内的布局,无论你的控件是如何深深插入,则可以从孩子的布局删除或任何父布局,如果布局中的树路径和此项目是从子布局构建的.
最简单的方法是在自定义表中保留指向所有项的指针列表.清除表格以重建它时,只需在您的小部件中执行此操作:
CustomTableItem* item;
while ( !items_.isEmpty() && ( (item = items_.takeFirst()) != 0 ) ){
layout()->removeWidget(item);
delete item; // It works no matter where the item is
}
items_.clear(); // clear the list afterwards.
Run Code Online (Sandbox Code Playgroud)
并且它完美地工作,自己也更新布局.如果要保留元素,只需跳过"删除项目"; 并在之后使用它们.
需要注意的一点是,不同的"删除"功能在QList或类似小部件以及QLayout中的工作方式不同(我在Qt Docs上理解).
在QList中,removeAt实际上删除了该对象.
(Qt 4.7 QList Docs)"删除索引位置i处的项目.我必须是列表中的有效索引位置(即0 <= i <size())."
在QLayout中,removeWidget或removeItem不会删除项目/窗口小部件,您有责任删除它,就像我之前做的那样.
(Qt 4.7 QLayout Docs)"从布局中删除小部件小部件.在此调用之后,调用者有责任为小部件提供合理的几何体或将小部件放回布局中."
希望能帮助到你.如果你看到任何错误,你可以告诉我,我会编辑答案!
有关删除此处的更多信息: 其他stackoverflow帖子
Qt中的小部件是常规C++对象,可以使用C++ delete运算符删除任何其他对象:
delete myWidget;
Run Code Online (Sandbox Code Playgroud)
在Qt中,小部件之间总是存在父子关系.当父窗口小部件被销毁时,它将删除其所有子窗口.通常,您不需要考虑显式删除任何小部件,而是考虑顶级小部件,即窗口和对话框.Qt将负责删除任何子窗口小部件.
QList::removeAt(int)不会删除已删除的对象,它只会从列表中删除该对象.如果您还想删除该对象,则必须执行以下操作:
delete myList.takeAt(0);
Run Code Online (Sandbox Code Playgroud)
这适用于诸如所有功能removeAt(int),takeAt(int),takeFirst()等他们从来没有删除对象,他们只从容器(列表,布局,scrollarea等)将其删除.在大多数情况下,窗口小部件的所有权随后被转移到调用者,(调用者负责在父子关系中断时删除窗口小部件),但不要假设总是这样,总是阅读函数的文档.
| 归档时间: |
|
| 查看次数: |
48867 次 |
| 最近记录: |