【问题标题】:How to properly use QLayouts (hbox, vbox, etc)?如何正确使用 QLayouts(hbox、vbox 等)?
【发布时间】:2018-09-25 07:10:55
【问题描述】:

我正在构建一个基于 QGraphicsWidget 的自定义小部件

在小部件内部,我需要与窗口大小一致的各种其他小部件。为此,我正在使用

Layout = new QGraphicsLinearLayout();
Layout->setOrientation(Qt::Horizontal);
setLayout(Layout);

所以我有一个布局,并且在布局的每一侧都有一个小部件。所以左侧有一个小部件,右侧有一个小部件。

 QGraphicsLinearLayout() below

      500 px wide x
|--------------------------------| 
|                                |
|left widget         right widget|   100 px tall y
|--------------------------------|

我想要当窗口变大时,小部件保持在边缘 x 像素内的行为。因此,如果将窗口的大小调整为 10,000 像素宽,则左侧小部件始终距离左边缘 1 像素,右侧小部件始终距离右边缘 1 像素。

                10000 px wide x
|---------------------------------------------------| 
|                                                   |
|left widget                            right widget|   100 px tall y
|---------------------------------------------------|

当前的行为是左侧小部件将保持原位并且永远不会移动,而右侧小部件将远离右侧边缘。

为了实现这种行为,我尝试了以下方法:

Layout->setAlignment(leftWidget, Qt::AlignLeft);

这完全没有任何作用。

我也试过

Layout->addItem(leftWidget);

Layout->setStretchFactor(leftWidget, 0);

Layout->addItem(rightWidget);

这会产生预期的效果,但会像这样将 rightWidget 与边框重叠

      500 px wide x
|--------------------------------| 
|                                |
|left widget                 right widget   100 px tall y
|--------------------------------|

那么我怎样才能得到我想要的行为呢?到目前为止,QLayouts 看起来很混乱,而且 API 具有误导性。

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    解决方案

    在左右小部件之间使用QGraphicsLinearLayout::addStretch 以使它们保持在两侧,并在小部件和边缘之间使用QGraphicsLayout::setContentsMargins 添加空间:

    auto *l = new QGraphicsLinearLayout();
    
    l->addItem(leftProxy);
    l->addStretch();
    l->addItem(rightProxy);
    l->setContentsMargins(25, 1, 1, 1);
    l->setSpacing(1);
    

    示例

    我已经为您准备了一个关于如何使用建议的解决方案的最小示例:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent)
    {
        auto *view = new QGraphicsView(this);
        auto *widget = new QWidget();
        auto *leftWidget = new QPushButton(tr("Left"));
        auto *rightWidget = new QPushButton(tr("Right"));
        auto *leftProxy = new QGraphicsProxyWidget();
        auto *rightProxy = new QGraphicsProxyWidget();
        auto *l = new QGraphicsLinearLayout();
        auto *sizeGrip = new QSizeGrip(widget);
    
        leftWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
        rightWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
    
        widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    
        widget->setMinimumSize(sizeGrip->sizeHint().width()
                               + leftWidget->sizeHint().width()
                               + rightWidget->sizeHint().width(),
                               leftWidget->sizeHint().height());
    
        leftProxy->setWidget(leftWidget);
        rightProxy->setWidget(rightWidget);
    
        l->addItem(leftProxy);
        l->addStretch();
        l->addItem(rightProxy);
        l->setContentsMargins(25, 1, 1, 1);
        l->setSpacing(1);
    
        view->setScene(new QGraphicsScene(this));
        view->scene()->addWidget(widget)->setLayout(l);
    
        widget->resize(400, 200);
    
        setCentralWidget(view);
        resize(640, 480);
    }
    

    【讨论】:

    • 这不起作用,当我调整我的小部件 leftWidget 和 rightWIdget 时不要移动。
    • addStrect(0) & setStretchFactor(leftWidget, 0) 不是一回事吗?
    • @IhaveAquestion,不,他们不是。为了知道为什么这对您不起作用并为您提供解决方案,您必须准备一个Minimal, Complete, and Verifiable example
    • addStrech(1) 给了我我需要的效果,但它像我描述的那样过度绘制了小部件。
    • @IhaveAquestion,如果您显示原因而不是尝试提出解决方案会更快。准备一个 MCVE。
    猜你喜欢
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    相关资源
    最近更新 更多