30

我有一个QScrollArea小部件,它开始为空;

空 QScrollArea

它有一个垂直布局,带有一个 QGridLayout 和一个垂直间隔以将其保持在顶部,并防止它延伸到整个滚动区域;

Qt 设计器中的 QScrollArea

在程序的其他地方,有一个 QTextEdit,它在更改时会扫描其内容以查找“物种”元素,然后将它们添加到 QGridLayout。任何已被移除的物种元素也会被移除。这一点有效;

带有奇怪滚动条的 QScrollArea

我一直打开垂直滚动条,这样当它出现时它就不会位于其他东西的顶部。请注意,尽管不需要,滚动条已经比滚动框大。

这就是问题。滚动区域似乎是预设的,我无法更改它。如果我向 QGridLayout 添加更多行,则滚动区域的大小不会增加。

相反,它保持相同的大小,并挤压 QGridLayout,使其看起来很丑(起初);

压扁的 QGridLayout

然后在添加更多之后它变得无法使用;

不可用的行编辑

请注意,滚动条的大小仍与之前的图像相同。前两张图片来自 Qt Designer,后三张来自正在运行的程序。

如果我调整窗口大小以使 QScrollArea 增长,那么我会看到:

愚蠢的太小布局

表示滚动区域内的某些布局未正确调整大小。

我的问题是;当我从 QGridLayout 添加和删除时,我需要做什么才能使小部件的可滚动区域动态调整大小?

4

4 回答 4

41

如果您从 Google 来到这里,但没有得到接受的答案,那是因为您错过了另一个秘密调用:QScrollArea::setWidget. 您必须创建并明确标识要滚动的单个小部件。仅将项目添加为子项是不够的!将多个项目直接添加到ScrollArea也不起作用。

这个脚本演示了一个简单的 QScrollArea 工作示例:

from PySide.QtGui import *

app = QApplication([])

scroll = QScrollArea()
scroll.setWidgetResizable(True) # CRITICAL

inner = QFrame(scroll)
inner.setLayout(QVBoxLayout())

scroll.setWidget(inner) # CRITICAL

for i in range(40):
    b = QPushButton(inner)
    b.setText(str(i))
    inner.layout().addWidget(b)

scroll.show()
app.exec_()
于 2016-10-19T18:49:36.270 回答
31

文档提供了一个答案:

widgetResizable : bool
此属性保存滚动区域是否应调整视图小部件的大小。如果此属性设置为 false(默认值),则滚动区域遵循其小部件的大小。

将其设置为真。

于 2012-10-08T12:26:03.473 回答
0

为什么不对行使用 QListView,它会为您管理所有问题?只需确保在添加后单击类(设计器的右上角窗口)并分配布局,否则它不会正确展开。

我在 QScrollArea 中使用 QLIstWidget 来制作可滚动的图像列表

尝试将其他对象添加到列表中,这就是我将图像添加到列表中的方式。

QImage& qim = myclass.getQTImage();

QImage iconImage = copyImageToSquareRegion(qim, ui->display_image->palette().color(QWidget::backgroundRole()));

QListWidgetItem* pItem = new QListWidgetItem(QIcon(QPixmap::fromImage(iconImage)), NULL);

pItem->setData(Qt::UserRole, "thumb" + QString::number(ui->ImageThumbList->count()));  // probably not necessary for you

QString strTooltip = "a tooltip"

pItem->setToolTip(strTooltip);

ui->ImageThumbList->addItem(pItem);
于 2016-08-30T10:34:11.850 回答
0

更新Artfunkel 的回答

这是一个 PySide6 演示,它使用“填充”按钮运行 for 循环,将项目添加到滚动区域。单击时,每个按钮也会自行删除。

from PySide6.QtWidgets import *

app = QApplication([])

scroll = QScrollArea()
scroll.setWidgetResizable(True) # CRITICAL

inner = QFrame(scroll)
inner.setLayout(QVBoxLayout())

scroll.setWidget(inner)  # CRITICAL


def on_remove_widget(button):
    button.deleteLater()


def populate():
    for i in range(40):
        b = QPushButton(inner)
        b.setText(str(i))
        b.clicked.connect(b.deleteLater)
        inner.layout().addWidget(b)

b = QPushButton(inner)
b.setText("Populate")
b.clicked.connect(populate)
inner.layout().addWidget(b)

scroll.show()
app.exec()
于 2021-09-04T18:44:05.707 回答