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()。所以我也是这样做的,但是这个工作但是:
我通过覆盖updateGeometries()并将header()移到顶部(在调用QTreeView :: updateGeometries();之后),在头部下方有未使用的区域。但我不确定这是否正确。
所以我的问题是: 实现“锁定”行的方法是setViewportMargins()文档,它们应该如何实现?
请注意,我知道另一种实现冻结行(或列)的方法 - Frozen Column Example。但这并不是我需要的,因为这种技术隐藏了主表(树)小部件的第一行(列)并在覆盖(静态)小部件中显示它。在我的情况下,我需要在标题下方区域中的不同信息,主要小部件应该实际向下移动以显示所有行
答案 0 :(得分:2)
实际上这是一个非常好的问题。就个人而言,我不认为setViewportMargins()是一种方法。通过使用viewportMargins,你唯一可以实现的是“移动”QTableView将绘制附加模型的边界,然后你必须通过绘制“冻结”行来处理周围的空白空间。使那些空白空间'所有者 - 绘制'你应始终寻找“主网格”的网格样式,字体大小等,以使“冻结”行/列看起来与主网格相同。
我尝试了几种方法,使编写代码变得非常好用和方便。最后,我最终制作了一个小部件,它结合了主网格(没有标题),顶部和左侧网格与标题+角落小部件。通过这样做,我可以非常直接地在主网格模型上使用模型过滤器处理冻结零件,以及为“冷冻”零件等分割器的简单方法。