Я пытаюсь поместить QVBoxLayout
внутри QScrollArea
, чтобы его можно было прокручивать по вертикали. Однако, похоже, что к нему не добавляются элементы.
Я увидел предложение создать внутренний виджет, который использует ScrollArea, и разместить внутри него макет, хотя, похоже, это не сработало. Моя структура должна выглядеть так:
+-------------------------------
| QScrollArea(realmScroll)
| +----------------------------
| | QWidget(realmScrollInner)
| | +-------------------------
| | | QVBoxLayout(realmLayout)
И код для этого:
# Irrelevant, added for context (this works)
centralWidget = QWidget(self)
self.container = QVBoxLayout(centralWidget)
centralWidget.setLayout(self.container)
self.setCentralWidget(centralWidget)
# Where trouble starts
self.realmScroll = QScrollArea(self.container.widget())
self.realmScroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.realmLayout = QVBoxLayout(self.container.widget())
self.realmScrollInner = QWidget(self.realmScroll)
self.realmScrollInner.setLayout(self.realmLayout)
self.realmScroll.setWidget(self.realmScrollInner)
self.container.addWidget(self.realmScroll)
# Doesn't add to realmLayout
self.realmLayout.addWidget(QLabel("test"))
Я все еще изучаю Qt (2 дня), поэтому я буду благодарен за подробные ответы на то, где я ошибаюсь.
Обновление :
Похоже, что addWidget (QLabel ())
работает до тех пор, пока realmScrollInner
не будет установлен как realmScroll
виджет. Поскольку я хотел бы добавить элементы после отображения пользовательского интерфейса, я должен сделать это, что, я не уверен, действительно правильно:
self.realmLayout.addWidget(QLabel("test"))
# realmScrollInner bound to realmScroll
realmScroll.setWidget(realmScrollInner)
self.container.addWidget(realmScroll)
# Access realmScroll's widget and then layout to add
realmScroll.widget().layout().addWidget(QLabel("test"))
Но если вы удалите этот первый вызов addWidget
перед виджет был привязан (поэтому в макете нет виджетов), а затем привязаны к виджетам ScrollArea, добавленные впоследствии, не отображаются. Возможно, ScrollArea нужно перерисовать (хотя я не вижу для этого метода)?
Обновление 2 : вызов repaint ()
для realmScroll или содержащегося в нем виджета ничего не делает, как и вызов активировать / обновить ()
в макете.
Хорошо, я только что закончил с этим бороться. Вот виджет, который может перейти в область прокрутки (scrollarea-> setWidget) и работать правильно. Он содержит QVBoxLayout и список пар метка / список виджетов, каждая из которых имеет собственную небольшую горизонтальную разметку, и делает в значительной степени то, что вам нужно.
Важным моментом было чтение раздела документации QScrollArea, посвященного подсказкам и размерам размера, и поиск бита, в котором было бы необходимо иметь sizeContraint QLayout :: SetMinAndMaxSize в макете.
class MappingDisplayWidget : public QWidget
{
Q_OBJECT
public:
explicit MappingDisplayWidget(QWidget *parent = 0);
void addFile(QString name);
private:
QVBoxLayout *m_layout;
QMap<QString, QListWidget *> m_mappings;
};
MappingDisplayWidget::MappingDisplayWidget(QWidget *parent) :
QWidget(parent)
{
m_layout = new QVBoxLayout;
m_layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
setLayout(m_layout);
}
void MappingDisplayWidget::addFile(QString name) {
if (m_mappings.find(name) == m_mappings.end()) {
QWidget *widg = new QWidget;
QHBoxLayout *lay = new QHBoxLayout;
widg->setLayout(lay);
QLabel *nlab = new QLabel(name);
lay->addWidget(nlab);
QListWidget *list = new QListWidget;
lay->addWidget(list);
m_layout->addWidget(widg);
m_mappings[name] = list;
}
}
Я сохраняю указатели на виджеты списка, чтобы потом добавить к ним материал, и это прекрасно работает.
Оказалось, что меня привели по неверному пути, поставив макет в качестве макета виджета. Реальный способ сделать это так же просто, как:
scrollarea = QScrollArea(parent.widget())
layout = QVBoxLayout(scrollarea)
realmScroll.setWidget(layout.widget())
layout.addWidget(QLabel("Test"))
Я уверен, что пытался изначально, но эй, это работает.
Однако это добавляет проблему, заключающуюся в том, что элементы макета сокращаются по вертикали, а не заставляют полосу прокрутки добавлять полосу прокрутки.