web-dev-qa-db-ja.com

スクロール可能なQVBoxLayoutを作成する方法は?

縦方向にスクロールできるように、QVBoxLayoutQScrollAreaの中に入れようとしています。ただし、アイテムが追加されていないようです。

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日後)を学習しているので、どこが間違っているのかについての詳細な回答をいただければ幸いです。

更新

realmScrollInnerrealmScrollのウィジェットとして設定されるまで、addWidget(QLabel())はすぐに機能するようです。 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"))
_

ただし、ウィジェットがバインドされる前にaddWidgetへの最初の呼び出しを削除すると(レイアウトにウィジェットがないため)、その後追加されたScrollAreaウィジェットへのバインドは表示されません。おそらく、ScrollAreaは再描画が必要です(ただし、そのためのメソッドは表示されません)。

pdate 2:レイアウトでrepaint()を呼び出す場合とは異なり、realmScrollまたはそのウィジェットに含まれるactivate/update()を呼び出しても何も起こりません。

25
Ross

レイアウトをウィジェットのレイアウトとして配置することにより、間違った道に導かれてしまったことがわかりました。これを行う実際の方法は、次のように単純です。

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

layout.addWidget(QLabel("Test"))

私が最初に試したのは確かですが、ちょっとうまくいきました。

ただしこれにより、スクロール領域にスクロールバーが追加されるのではなく、レイアウトのアイテムが垂直方向に縮小されるという問題が追加されます。

9
Ross

わかった、これで戦い終わったところだ。これは、スクロール領域(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;
    }
}

私はリストウィジェットへのポインターを保持しているので、後でそれらに項目を追加でき、それは正常に機能します。

7
Michael Kohne

電話してみてください

self.realmScroll.setWidgetResizable(True)
2
baysmith