如何在QT中的树视图项内渲染复杂的小部件?

时间:2010-01-26 19:53:25

标签: qt delegates view

我在QT模型/视图框架中遇到以下问题。我想在表视图项中呈现一个小部件。

首先我的想法是使用

void QAbstractItemView::setIndexWidget( const QModelIndex & index, QWidget * widget )

但是这个函数的文档明确指出:

  

此功能仅适用于   显示内部的静态内容   与项目对应的可见区域   数据的。如果要显示自定义   动态内容或实现自定义   编辑器小部件,子类QItemDelegate   代替。

所以他们建议在这里使用代表。好吧,到目前为止一切顺利。我知道代理可能会用来创建一个编辑器,它基本上可以是任何QT小部件。但问题出在这里 - 我不希望这个小部件成为编辑器 - 我想总是用这个小部件渲染项目。而不仅仅是“渲染”,我需要它来获得小部件的确切行为。

现在我要使用的小部件是一个自定义小部件,它是一些其他小部件的容器(几个复选框,几个带有一些布局的按钮)。

我考虑的解决方案是这样的:

  1. 将我的自定义小部件的外观抓取到像素图。
  2. 让代表使用此像素图绘制自己。
  3. 当鼠标悬停在项目上时会导致视图自动开始编辑(我不是 知道怎么做,但我想这是可能的)
  4. 让代理人创建我的小部件作为项目的编辑器。
  5. 这个解决方案似乎有效,但它对我来说闻起来很糟糕。对于这个问题,任何人都可以提出更优雅的解决方案吗?

    感谢。

2 个答案:

答案 0 :(得分:7)

Delegates负责creating editors以及进行所有必要的展示。他们可以使用样式来绘制大部分绘画,例如绘制进度条或手动绘制。

但是,委托不是小部件。除非调用了编辑器,否则它无法访问小部件所能做的大多数事情。这两者是非常不同的,有不同的目的,并完成不同的事情。

代表们最麻烦的一点是他们静态。除非模型中的某些内容触发更新(或者窗口小部件配置为监视悬停事件),否则代理将不会用于重绘任何存在的数据 - 缓冲的表示将被绘制到屏幕上。

您可以控制何时使用edit triggers调用编辑器,尽管您可以使用某些自定义代码(例如通过鼠标跟踪)来处理它。

答案 1 :(得分:0)

您可以为永久拥有一个复杂小部件的每个单元格调用QAbstractItemView.openPersistentEditor(index)。完成这项工作的两个关键:

  1. QStyledItemDelegate.sizeHintChanged.emit(index)随时需要在编辑器小部件的大小更改时调用。
  2. 实施QStyledItemDelegate.sizeHint()可能很棘手且乏味(或者假设您在index.internalPointer().editor_widget.sizeHint()期间将编辑器的引用保存到内部指针,则可以执行QStyledItemDelegate.createEditor()

我最近使用了openPersistentEditor方法在树视图中呈现表,但是应该指出的是,打开编辑器的成本很高,因此,如果您有成千上万的索引并且一次都加载了它们,则可能需要花费一个而。有很多方法可以缓解此问题:

  1. 使用线程增量加载模型
  2. 使用Qt的fetchMore()机制
  3. 逐步调用openPersistentEditor(使用计时器,或当它们首次出现时)
  4. 在父级展开时调用openPersistentEditor,在父级折叠时调用closePersistentEditor,并且可能限制在具有多个子级的节点上使用全部展开。