QT MVC 内存管理

目的

主要是是探讨对于MVC,内存是否要进行管理, 以QLIstWidget, QLIstModel, QListWidgetItem 为例。
如果绑定了某个QWidget 是否要手动删除item 与 对应绑定的QWIdget。 结果是不用的。

验证

已添加10000个item为例。

  1. 没有添加item,只有listwidget, 内存为9.9M, 调用clear 内存具体波动。
  2. 有item, ,有listwidget, 没有绑定 QWidget , 内存为11.1M, 调用clear内存将为10.8M
  3. 有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);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道阻且长,行则降至

无聊,打赏求刺激而已

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值