【发布时间】:2020-12-08 09:36:05
【问题描述】:
在我目前使用的专有代码库中,有一个自定义列表视图(派生形式 QListView)。
目前当大量项目 (>10000) 使主线程冻结时会出现问题。 视图中的每个项目都是在 QtDesigner 中设计的自定义小部件。
为了渲染每一行,我们使用setIndexWidget,它在QAbstractItemModel::rowsInserted 信号上调用。对于每个插入的行,为每个索引设置从first 到last 的自定义小部件。
我尝试将此代码移植到使用QStyledItemDelegate,因为断开项目小部件与实际模型的连接似乎可以解决渲染缓慢的问题。
在这种情况下,Qt5 可以按需懒惰地渲染视图中的项目。在显示列表之前,我们不需要为视图创建每个小部件。
我使用派生自QStyledItemDelegate 的类取得了初步成果。我在构造函数中创建了一个列表项小部件,然后像这样覆盖绘制事件。
void paint(QPainter *painter, const QStyleOptionViewItem &option,const QModelIndex &index) const override {
auto baseWid = getBaseWidget(); // Get's list item widget pointer
setSubEditorData(baseWid,index); // Set's it's state to display current item
baseWid->resize(option.rect.size());
QPixmap pixmap(option.rect.size());
baseWid->render(&pixmap);
painter->drawPixmap(option.rect, pixmap);
}
这对于静态内容来说已经足够了,但是我的小部件有复选框并且可以被选中。
我真的不明白如何使它具有交互性,同时保留代表提供的好处(按需渲染等)。
我的问题是如何让委托处理用户事件?就像鼠标点击一样,选择会发生变化。
Qt5 的例子覆盖委托太简单了,我不明白如何用委托绘制一个自定义的小部件。
【问题讨论】:
-
为什么它一次插入 10K 小部件而不是按需获取它们?我认为您应该修复模型而不是委托。
-
@vahancho 遗留代码
-
能否覆盖原始模型并在视图中替换它?
-
@vahancho 是的,有可能。