【问题标题】:Get QScrollArea absolute size获取 QScrollArea 绝对大小
【发布时间】:2019-03-13 10:56:45
【问题描述】:

我有一个自定义小部件,它是 QScrollArea 的子部件。 无论是否显示滚动条,我都需要获取QScrollArea 的绝对大小。

class MyWidget : public QWidget { /*...*/ };

void
MyWidget::Foo()
{
    auto scrollAreaHeight = parentWidget()->height();
    auto scrollAreaWidth = parentWidget()->width();

    /* height and width change depending on scrollbars 
       being displayed or not */
}

有没有办法做到这一点?

或者,如果通过parentWidget() 函数返回的QWidget 接口不可能做到这一点,有没有办法从QScrollArea 本身获取QScrollArea 的绝对大小?

【问题讨论】:

  • 我猜parentWidget() 返回滚动区域的viewport。因此,宽度和高度会根据滚动条是否可见而变化。使用parentWidget()->parentWidget()->size(),它可能会更好。但是,如果小部件假定某个父小部件,我会认为此解决方案很脆弱。可能是,你应该考虑直接从QAbstractScrollArea 派生你的小部件来解决这个问题。

标签: qt qwidget qscrollarea


【解决方案1】:

我完全不明白为什么 OP 无法获得QScrollArea 的绝对大小。

但是,我认为 OP 的理解中可能缺少某些内容。我准备了以下小样本:

QWidgetQVBoxLayoutQScrollAreaQPushButton

#!/usr/bin/python3

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QScrollArea, QPushButton

app = QApplication(sys.argv)
qWinMain = QWidget()
qVBox = QVBoxLayout()
qScrollArea = QScrollArea()
qBtn = QPushButton("Consume somehow some space\nConsume somehow some space\nConsume somehow some space\n")
qScrollArea.setWidget(qBtn)
qVBox.addWidget(qScrollArea)
qWinMain.setLayout(qVBox)
qWinMain.show()

def onBtnClicked():
  print("Sizes:")
  print("qWinMain:               ", qWinMain.size())
  print("qWinMain.childrenRect():", qWinMain.childrenRect().size())
  print("qScrollArea:            ", qScrollArea.size())
  print("qScrollArea.viewport(): ", qScrollArea.viewport().size())
  print("qBtn:                   ", qBtn.size())

qBtn.clicked.connect(onBtnClicked)
sys.exit(app.exec_())

单击QPushButton 时,会打印一些尺寸的小部件。 它这样做了两次——一次是在滚动条不可见时,一次是在我更改主窗口的大小以使滚动条变得可见之后。

输出:

Sizes:
qWinMain:                PyQt5.QtCore.QSize(225, 100)
qWinMain.childrenRect(): PyQt5.QtCore.QSize(203, 78)
qScrollArea:             PyQt5.QtCore.QSize(203, 78)
qScrollArea.viewport():  PyQt5.QtCore.QSize(201, 76)
qBtn:                    PyQt5.QtCore.QSize(201, 65)
Sizes:
qWinMain:                PyQt5.QtCore.QSize(120, 92)
qWinMain.childrenRect(): PyQt5.QtCore.QSize(98, 70)
qScrollArea:             PyQt5.QtCore.QSize(98, 70)
qScrollArea.viewport():  PyQt5.QtCore.QSize(82, 54)
qBtn:                    PyQt5.QtCore.QSize(201, 65)

所以,这就是如何阅读:

  • qWinMain.size() 返回的客户区大小为 qWinMain(不考虑窗口装饰)。
  • qWinMain.childrenRect().size() 返回 qWinMain 子级的边界框大小 - 它的宽度和高度正好小 22 个像素,因为 11 个像素是 QWidget 的默认边距。
  • qScrollArea.size() 在这两种情况下都返回了与 qWinMain.childrenRect().size() 完全相同的大小,这是合理的,因为它是唯一的孩子。
  • qScrollArea.viewport().size() 返回QScrollArea 的视口大小——该大小取决于滚动条是否可见。如果没有滚动条,与qScrollArea 的区别在宽度和高度上只有 2 个像素,但如果有滚动条,则分别更大。
  • qBtn.size() 返回按钮的大小,独立于其视觉/剪辑区域,因此在两种情况下都相等。

所以,无论 OP 表示“QScrollArea 的绝对大小”是什么意思——其中之一应该是 OP 正在寻找的。​​p>

【讨论】:

  • @Unimportant 抱歉,我是在 PyQt 中完成的。实际上,C++ 是我的“原生”语言。但是,1)你没有标记任何语言 2)Python 代码更短 3)C++ 中的原理没有改变。
  • 谢谢,我需要一些时间来了解这个。
  • 你说得对,QScrollArea::width()QScrollArea::height() 返回滚动区域的绝对大小,而从滚动区域的子窗口小部件中调用 parentWidget()->width()parentWidget()->height() 返回滚动区域的视口大小。这让我大吃一惊。
猜你喜欢
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 2014-11-20
  • 2010-09-19
  • 1970-01-01
相关资源
最近更新 更多