4

void QAbstractScrollArea::setViewportMargins(int left, int top, int right, int bottom) 的文档说:

将滚动区域周围的边距设置为左、上、右和下。这对于具有“锁定”行和列的电子表格等应用程序很有用。边缘空间留空;将小部件放在未使用的区域。注意这个函数经常被QTreeView和QTableView调用,所以边距必须由QAbstractScrollArea子类实现。此外,如果要在项目视图中使用子类,它们不应调用此函数。

首先,我对描述本身感到困惑。该功能不是虚拟的,因此我不应该重新实现它以提供我的利润。如果我应该调用它而不是什么时候,在什么时候?如果 QTreeView 在内部使用自己的值调用它,那么我们的调用将如何协作?查看 Qt 源代码,我发现 QTreeView::updateGeometries() 确实使用参数(基本上)0、headerHeight、0、0 调用它。那么我应该重新实现 updateGeometries() 吗?

进一步谷歌搜索我发现其他人从重写的 resizeEvent() 调用 setViewportMargins()。所以我也这样做了,这有效但是:

  1. 我想知道这种技术如何与内部 QTreeView::updateGeometries() 共存,该内部 QTreeView::updateGeometries() 使用本质上是硬编码的参数调用 setViewportMargins() (如果 header 被隐藏,则只有 headerHeight 更改为 0)?
  2. 虽然它有效,但“未使用区域”出现在标题上方。但是要实现文档中提到的“锁定”行,需要将此区域放在标题下

通过覆盖 updateGeometries() 并将 header() 移动到顶部(在调用 QTreeView::updateGeometries(); 之后),我在标题下方获得了未使用的区域。但我不确定这样做是否正确。

所以我的问题是: setViewportMargins() 文档意味着什么实现“锁定”行的方法以及它们应该如何实际实现?

请注意,我知道另一种实现冻结行(或列)的方法 - Frozen Column Example。但这并不是我所需要的,因为这种技术隐藏了主表(树)小部件的第一行(列)并将其显示在覆盖(静态)小部件中。在我的情况下,我需要在标题下方区域中提供不同的信息,并且主小部件实际上应该向下移动以显示所有行

4

1 回答 1

2

其实这是一个非常好的问题。就我个人而言,我不认为 setViewportMargins() 是一种方法。通过使用 viewportMargins,您唯一可以实现的就是“移动”QTableView 将绘制附加模型的边界,然后您必须通过绘制“冻结”行等来处理周围的空白空间。让这些空白空间“所有者绘制”你应始终寻找“主网格”的网格样式、字体大小等,以使您的“冻结”行/列看起来与主网格相同。

我尝试了几种方法来使编写代码变得非常好和方便。最后,我最终制作了结合主网格(无标题)、顶部和左侧网格与标题+角小部件的小部件。通过这样做,我有了非常直接的方法来处理在主网格模型顶部使用模型过滤器的冻结部件,以及为“冻结”部件等设置分离器的简单方法。

于 2013-08-05T08:58:38.107 回答