Как создать прокручиваемый QVBoxLayout? - PullRequest
24 голосов
/ 04 июля 2011

Я пытаюсь поместить 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 дня), так что углубленноответы на то, куда я иду не так, как следуеткак виджет 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 или содержащегося в нем виджета ничего не делает, как и вызов activate/update() на макете.

Ответы [ 3 ]

8 голосов
/ 04 июля 2011

Оказалось, что меня привели по неверному пути, поставив макет как макет виджета.Фактический способ сделать это так просто:

scrollarea = QScrollArea(parent.widget())
layout = QVBoxLayout(scrollarea)
realmScroll.setWidget(layout.widget())

layout.addWidget(QLabel("Test"))

Я уверен, что я пытался изначально, но эй, это работает.

Однако это добавляетпроблема в том, что элементы макета сокращаются по вертикали, вместо того, чтобы прокрутка добавляла полосу прокрутки.

6 голосов
/ 30 марта 2012

ОК, я только что закончил бороться с этим. Вот виджет, который может перейти в область прокрутки (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;
    }
}

Я сохраняю указатели на виджеты списков, чтобы потом к ним можно было что-то добавить, и это прекрасно работает.

2 голосов
/ 04 июля 2011

Попробуйте позвонить

self.realmScroll.setWidgetResizable(True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...