如何创建可滚动的QVBoxLayout?

Ros*_*oss 24 qt pyqt

我试图在QVBoxLayout里面放一个QScrollArea,以便它可以垂直滚动.但是似乎没有添加项目.

我看到一个建议,我应该创建一个ScrollArea使用的内部窗口小部件,并将布局放在其中,尽管它似乎没有用.我的结构应该是这样的:

+-------------------------------
| QScrollArea(realmScroll)
| +----------------------------
| | QWidget(realmScrollInner)
| | +-------------------------
| | | QVBoxLayout(realmLayout)
Run Code Online (Sandbox Code Playgroud)

以及执行此操作的代码:

# 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"))
Run Code Online (Sandbox Code Playgroud)

我还在学习Qt(2天),所以对我出错的地方的深入解答将不胜感激.

更新:

似乎addWidget(QLabel())工作一直到realmScrollInner被设置为realmScroll小部件.由于我想在UI显示后添加元素,我必须这样做,我不确定是否正确:

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"))
Run Code Online (Sandbox Code Playgroud)

但是如果addWidget在绑定窗口小部件之前删除第一次调用(因此布局没有窗口小部件),则绑定到之后添加的ScrollArea窗口小部件不会显示.也许ScrollArea需要重新绘制(虽然我没有看到一种方法)?

更新2:调用repaint()realmScroll或其包含的小部件什么也不做,就像调用activate/update()布局一样.

Ros*_*oss 9

事实证明,通过将布局作为窗口小部件的布局,我走错了路.实现此目的的实际方法很简单:

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

layout.addWidget(QLabel("Test"))
Run Code Online (Sandbox Code Playgroud)

我很确定我最初尝试过,但是嘿它正在工作.

但是,这会增加布局项目垂直收缩而不是使scrollarea添加滚动条的问题.


Mic*_*hne 7

好的,我刚刚完成了与此战斗.这是一个小部件,可以进入滚动区域(scrollarea-> setWidget)并正常工作.它包含一个QVBoxLayout和一个label/listwidget对列表,每个都在它们自己的小水平布局中,它几乎可以满足您的需求.

重要的是阅读关于大小提示和布局的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我保持指向列表小部件的指针,以便我可以在以后添加内容,并且工作正常.


bay*_*ith 2

尝试打电话

self.realmScroll.setWidgetResizable(True)
Run Code Online (Sandbox Code Playgroud)