【问题标题】:How to render a a complex widget inside a tree view item in QT?如何在 QT 的树视图项中呈现复杂的小部件?
【发布时间】:2010-01-26 19:53:25
【问题描述】:

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

首先我的想法是使用

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

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

这个函数应该只用于 显示静态内容 与项目对应的可见区域 数据的。如果要显示自定义 动态内容或实现自定义 编辑器小部件,子类 QItemDelegate 而是。

所以他们建议在这里使用代表。嗯,到目前为止一切顺利。我知道委托可以用来创建一个编辑器,它基本上可以是任何 QT 小部件。但问题是——我不希望这个小部件成为编辑器——我想始终使用这个小部件呈现项目。而不仅仅是“渲染”,我需要它具有小部件的确切行为。

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

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

  1. 将我的自定义小部件的外观添加到像素图。
  2. 让代理使用此像素图绘制自己。
  3. 当鼠标悬停在某个项目上时,视图会自动开始编辑(我没有
    知道怎么做,但我想这是可能的)
  4. 让代理创建我的小部件作为项目的编辑器。

这个解决方案似乎有效,但对我来说闻起来很糟糕。谁能为这个问题提供更优雅的解决方案?

谢谢。

【问题讨论】:

  • 你是什么意思“我需要它来获得小部件的确切行为?
  • 我的意思是与用户互动——对用户的行为做出反应
  • 你想要什么样的互动?每个细胞就是那样,一个细胞。它不是一个小部件,所以我很难想象你真正想要的交互方式。

标签: qt delegates view


【解决方案1】:

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

但是,委托不是小部件。除非调用了编辑器,否则它无法访问小部件的大部分内容。两者截然不同,目的不同,完成的事情也不同。

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

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

【讨论】:

  • 同意。所以基本上你说,我正朝着正确的方向前进?顺便说一句,悬停事件在这里对我没有帮助,因为小部件仅在触发编辑时由委托创建(在此之前小部件不存在)。
  • 您可以使用合成,保存对小部件的引用,然后使用QWidget::render() 绘制到在代理的paint 方法中绘制的像素图。
【解决方案2】:

您可以为每个需要永久拥有复杂小部件的单元格调用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,并可能限制在具有许多子节点的节点上使用expand-all。

【讨论】:

  • 这很有用,谢谢。但我还有一个额外的挑战——编辑可以改变树结构。当索引的值发生变化时,您有什么建议如何打开/关闭索引的子编辑器? (我想始终显示“父”节点的编辑器——正在展开和折叠的节点,并在展开时显示所有子节点的编辑器。)。如果我只是按照您的建议使用 open/closePersistentEditor ,那么当编辑导致它们消失时,子编辑器不会被删除。
  • 你可以使用 QT 文档中的 QAbstractItemModel.moveRow() 或信号 rowsAboutToBeMoved():“注意:连接到此信号的组件使用它来适应模型尺寸的变化。”,关闭孩子们的编辑?
猜你喜欢
  • 2012-11-22
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 2013-12-21
  • 1970-01-01
  • 2010-12-24
相关资源
最近更新 更多