0

QScrollArea出于某种原因,contentMargins在我将QGraphicsView设置为其小部件时忽略了该设置。看看下面的片段,有人可以告诉我是我做错了什么还是SDK中的错误?

片段 1(完美运行):

QWidget *appWindow = new QWidget;

QScrollArea *sa = new QScrollArea(appWindow);
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setContentMargins(50, 50, 50, 50);

QWidget *widgetToScroll = new QWidget(sa);
widgetToScroll->resize(5000, 5000);
sa->setWidget(widgetToScroll);

QVBoxLayout *appWindowLayout = new QVBoxLayout(appWindow);
appWindowLayout->addWidget(sa);
appWindow->setLayout(appWindowLayout);

appWindow->show();

片段 2(就像setContentMargins()调用被完全忽略):

QWidget *appWindow = new QWidget;

QScrollArea *sa = new QScrollArea(appWindow);
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setContentMargins(50, 50, 50, 50);

QGraphicsView *widgetToScroll = new QGraphicsView(new QGraphicsScene(sa), sa);
widgetToScroll->setAlignment(Qt::AlignLeft | Qt::AlignTop);
widgetToScroll->resize(5000, 5000);
sa->setWidget(widgetToScroll);

QVBoxLayout *appWindowLayout = new QVBoxLayout(appWindow);
appWindowLayout->addWidget(sa);
appWindow->setLayout(appWindowLayout);

appWindow->show();

谢谢。

4

2 回答 2

4

为了使 QScrollArea 小部件的内容边距正常工作,我将其子类化并手动设置视口边距(这是 QT 4.7 中的受保护方法)

// Extended class
class QScrollAreaWithMargins : public QScrollArea
{
public:

    virtual void resizeEvent(QResizeEvent *event) override
    {
        // Define content margins here
        setViewportMargins(5, 0, 0, 0); // <<<<< SET MARGINS HERE
        QScrollArea::resizeEvent(event);
    }
};

// Usage
//...
mEditorScrollArea = new QScrollAreaWithMargins();
//...
于 2012-06-29T20:29:47.457 回答
3

看起来您对如何嵌套 QGraphicsView 和 QGraphicsScene 的结构感到困惑。(也许这只是一个错字?)

    QGraphicsView *widgetToScroll = new QGraphicsView(new QGraphicsScene(sa), sa);

应该改为

    QGraphicsView *widgetToScroll = new QGraphicsView(new QGraphicsScene(), sa);

或者

    QGraphicsView *widgetToScroll = new QGraphicsView();
    sa->setWidget(widgetToScroll);

当您将 QWidget 添加到布局时,您会更改小部件的父级。当您将一个小部件(或 QGraphicsView)设置为 QScrollArea 时,您更改了该小部件的父级。有关详细信息,请参阅对象树和所有权。因此,如果您想在 QScrollArea 中设置 QGraphicsView,您的代码将如下所示:

    QWidget *appWindow = new QWidget;

    QScrollArea *sa = new QScrollArea(); // No need to specify a parent here if
                                         // you add it to a layout later
    sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    sa->setContentsMargins(50, 50, 50, 50);

    QGraphicsView *widgetToScroll = new QGraphicsView();
    widgetToScroll->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    widgetToScroll->resize(5000, 5000);
    sa->setWidget(widgetToScroll); // This sets the parent for widgetToScroll

    QVBoxLayout *appWindowLayout = new QVBoxLayout();
    appWindowLayout->addWidget(sa); // This sets the parent for sa
    appWindow->setLayout(appWindowLayout); // This sets the parent for appWindowLayout

    appWindow->show();

作为旁注...

当使用带有 QGraphicsScene 的 QGraphicsViews 时,我没有使用 QScrollArea 的 setContentsMargins 设置边距,而是使用 QGraphicsView 自动滚动并将场景矩形设置为具有比我的内容大小更大的边距,如下所示:

    QWidget *appWindow = new QWidget;

    QGraphicsView *widgetToScroll = new QGraphicsView();
    QGraphicsScene *scene = new QGraphicsScene();
    scene->addRect(0,0, 5000, 5000);

    widgetToScroll->setSceneRect(-50,-50, 5050, 5050);
    widgetToScroll->setScene(scene);

    QVBoxLayout *appWindowLayout = new QVBoxLayout(appWindow);
    appWindowLayout->addWidget(widgetToScroll);

    appWindow->setLayout(appWindowLayout);
    appWindow->show();

QGraphicsView 包含的不仅仅是在需要时自动滚动。您可以调整其中的所有内容以及更多内容。它非常适合 2D 布局、交互和动画。有关更多信息,请参阅http://doc.qt.io/qt-5/graphicsview.html上的Qt 图形视图框架。

以下是使用边距和填充时可能有用的更多信息:QStyleSheets 使用的盒子模型。

于 2011-10-20T07:35:04.313 回答