计算 QTableWidget 所需的确切高度(Qt 6 更新)

问题描述 投票:0回答:1

计算

QTableWidget
所需的高度以使所有行都可见且不添加滚动条时,仅获取行数、将行数乘以行高并加上标题的高度是不够的。必须再添加一些像素,这似乎取决于所使用的样式。

几年前,我要求解决这个问题,相应的帖子中给出的提示适用于 Qt 5:可以通过获取小部件的高度并减去视口高度和标题高度来计算附加像素。

使用 Qt 6 和 Plasma 6,这不再适用于所有样式。

它仍然适用于 Fusion,例如小部件高度为 480 像素,视口高度为 456,标题为 22,得到我需要的 2 像素:

Example using the Fusion style

但使用 Breeze 时,高度不同:小部件为 480 像素,视口为 450 像素,标题为 30 像素,结果为 0(我们需要 4 像素)。因此,当我使用 Breeze 时,我再次得到滚动条:

Example using the Breeze style

所以问题是一样的:如何可靠地计算我需要添加的额外像素?

c++ qt qtablewidget qt6
1个回答
0
投票

tl;博士

对于基于 QTableView 的类,您应该考虑其垂直标题的高度(即使它不可见)、水平标题的可能高度(如果可见)以及视图的边距。

确保小部件也通过样式进行抛光也是强制性的。

说明

首先,我们几乎永远不能依赖小部件的初始大小。

默认情况下,所有标准 Qt 小部件在创建后将立即返回以下

size()

  • 640x480 对于在其构造函数中没有父 QWidget 创建的任何小部件;假设是它可能是一个顶级小部件(一个窗口);
  • 100x30 对于在其构造函数中使用父 QWidget 创建的任何小部件;

上面的内容是硬编码在常见的 QWidget 源代码中,唯一的例外是那些在自己的构造函数中显式地设置了大小限制的小部件(AFAIR,没有标准的 Qt 小部件会这样做):例如,对

setMinimumHeight(100) 的调用
可以覆盖在没有父级的情况下创建的小部件的高度,或者
setMaximumWidth(500)
可以对使用父级创建的小部件执行相同的操作。 尽管如此,小部件的 size()
的结果只会在应用后才会考虑上述内容。
也就是说,考虑 widget 的继承路径很重要;在这一点的情况下:

QTableWidget
  1. QTableView
  2. QAbstractItemView
  3. QAbstractScrollArea
  4. Q框架
  5. QWidget
  6. Q对象
  7. 这意味着每个继承级别都可能覆盖或继承(在某种程度上)它所基于的类的行为。

在这种特定情况下,必须考虑 QFrame

frameWidth

 属性,它是用于视图的框架边框的宽度。
但请注意,该值

可能

不可靠,因为样式(具体来说,使用具有可变边框宽度的 QSS)可能会使用不一致的边框。 上述一点也间接重要:小部件必须被

抛光

才能检索正确的框架宽度;小部件的 QStyle 必须应用于小部件,这始终很重要:小部件可以继承样式,或者无论是否是顶级小部件(窗口),其行为都会有所不同。风格本身可能会根据父母的不同,选择以不同的方式“打磨”各个方面。一些内部值可能会在创建时设置,并且仅在重新设置父级/重新设计样式时重置,并且大小提示也可能会被缓存。 因此,为了获得(可能的)合适的高度,您需要:

确保小部件已经是最终小部件结构的一部分(必须正确设置
    至少
  1. 到顶级窗口),以便准确设置/调整样式; 调用
  2. ensurePolished()
    ,以便重置任何可能的缓存值(包括间接值和大小提示);
    使用垂直标题的
  3. length()
     获取视图项目的正确高度(通常比仅将第一行的 
    rowHeight()
    乘以行数更准确,并且比迭代所有行更快,因为标题可能已经做到了);
    添加 
  4. frameWidth()
  5. ,但加倍(因为您必须考虑顶部和底部边距),同时希望样式/QSS 对所有边使用相同的值;
    
    
  6. 请注意,更合适的方法应该在视图的
sizeHint()

minimumSizeHint()
覆盖中执行上述操作,同时与可能的模型布局更改保持一致,并确保设置正确的
sizeAdjustPolicy
 属性值。

© www.soinside.com 2019 - 2024. All rights reserved.