setViewportMargins()和“已锁定”的行和列

时间:2013-08-05 08:09:20

标签: qt frozen-columns

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()共存,它使用基本上硬编码的参数调用setViewportMargins()(如果标题被隐藏,则headerHeight只会更改为0)?
  2. 虽然它有效但“未使用的区域”出现在标题上方。但是要实现文档中提到的“锁定”行,需要将此区域置于标题
  3. 我通过覆盖updateGeometries()并将header()移到顶部(在调用QTreeView :: updateGeometries();之后),在头部下方有未使用的区域。但我不确定这是否正确。

    所以我的问题是: 实现“锁定”行的方法是setViewportMargins()文档,它们应该如何实现?

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

1 个答案:

答案 0 :(得分:2)

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

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