目的
主要是是探讨对于MVC,内存是否要进行管理, 以QLIstWidget, QLIstModel, QListWidgetItem 为例。
如果绑定了某个QWidget 是否要手动删除item 与 对应绑定的QWIdget。 结果是不用的。
验证
已添加10000个item为例。
- 没有添加item,只有listwidget, 内存为9.9M, 调用clear 内存具体波动。
- 有item, ,有listwidget, 没有绑定 QWidget , 内存为11.1M, 调用clear内存将为10.8M
- 有item, ,有listwidget, 绑定QWidget 内存为20.8M 调用内存将为11.8M
证明调用clear 是可以清除绑定的QWIdget与 item. 如果是自定义的QWidget,里面有指针数据 ,可在析构的时候, 实现内存释放。
setItemWidget 已经将item 与 QWidget绑定, 里面有一个 追踪QAbstractItemView setIndexWidget
...
if(widget)
{
widget->setParent(viewport());
...
d->addEditor(index, widget, true)); //静态的
}
...
参考源码追踪, (QT 5.7.1)
void QListWidget::clear()
{
Q_D(QListWidget);
selectionModel()->clear();
d->listModel()->clear();
}
void QListModel::clear()
{
beginResetModel();
for(int i = 0; i < items.count(); ++i)
{
if(item.at(i))
{
items.at(i)->d->theid = -1;
items.at(i)->view = 0 ;
delete items.at(i);
}
}
items.clear();
endResetModel();
}
QLIstModel 继承于 QAbstractItemModel
beginResetModel 解释有如下说明: Any views attached to this model will be reset as well, 任何绑定这个model的view 也会reset。
然后我们查看QAbstractItemView reset.
foreach(cosnt QEditorInfo &info, d->indexEidtorHash)
{
if(info.widget)
{
d->releaseEditor(info.widget.data(), d->indexForEditor(info.widget.data()));
}
}
QAbstractItemViewPrivate releaseEditor 是由有对QWidget绑定进行删除-delegate 显示editor
inline void releaseEditor(QWidget* editor, const QModelIndex& index = QModelIndex()) const
{
if(editor)
{
QObject::disconnect(editor, SIGNAL(destroyed(QObject*)), q_func(), SLOT(editorDestroyed(QObject*)));
editor->removeEventFilter(itemDelegate);
editor->hide();
QAbstractItemDelegate* delegate = delegateForIndex(index);
if(delegate)
delegate->destroyEditor(editor, index);
else
editor->deleLator();
}
}
所以我们clear是可以的。
重载QAbstractItemDelegate 中 createEditor 与 QAbstractItemView setIndexWidget 为啥显示窗口一个是要双击编辑才显示, 另一个是直接显示窗口不用双击编辑才行。
先了解这个结构体
struct QEditorInfo
{
QEditorInfo(QWidget* e, bool s):widget(QPointer<QWidget>(e)), isStatic(s){}
QEditorInfo():isStatic(false){}
QPoint<QWudget> widget;
bool isStatic;//区分静态还是动态的
主要在于isStatic为false, 还是true
QAbstractItemViewPrivate addEditor
void QAbstractItemViewPrivate::addEditor(const QModelIndex& index, QWidget* editor, bool isStatic)
{
...
indexEditorHash.insert(index, QEditorInfo(editor, isStatic));
...
}
对于无论是QAbstractItemDelegate 中 createEditor 重写后还是setItemWidget, 视图最终返回editor
QWidget* QAbstarctItemViewPrivate::editor(const QModelIndex& index, cosnt QStyleOptionViewItem &options)
{
Q_Q(QAbstarctItemView);
QWidget *w = editorForIndex(idnex).widget.data();
if(!W)
{
.... //通过一系列操作委托中QWidget
w = delegate->createEditor(viewport, options, index);
if(w)
{
w->installEventFilter(delegate);
...
delegate->setEditorData(w, index);
addEditor(index, w,false); //动态的
}
...,
}
return w;
}
最后在 QAbstarctItemViewPrivate中的updateEditorData 是否调用编辑数据更新,里面有个
if(it.value().isStatic || ...) //表示如果是静态的 那么就在遍历过程直接便利下一个 不用更新委托数据
continue;,
QAbstractItemDelegate * delegate = delegateForIndex(index);
if(delegate)
{
delegate->setEditorData(editor, index);
}