이 페이지에서

기본 그래픽 레이아웃 예시

기본 그래픽 레이아웃을 만드는 방법을 보여줍니다.

'기본 그래픽 레이아웃' 예제는 QGraphicsView 에 있는 레이아웃 클래스( QGraphicsLinearLayout 및 QGraphicsGridLayout)를 사용하는 방법을 보여줍니다. 또한 사용자 정의 레이아웃 항목을 작성하는 방법도 설명합니다.

'기본 레이아웃 예제'의 스크린샷

Window 클래스 정의

Window 클래스는 QGraphicsWidget 의 서브클래스입니다. 이 클래스에는 QGraphicsWidget parent 를 매개변수로 받는 생성자가 있습니다.

class Window : public QGraphicsWidget
{
    Q_OBJECT
public:
    Window(QGraphicsWidget *parent = nullptr);

};

Window 클래스 구현

Window 의 생성자는 세로 방향(vertical)의 QGraphicsLinearLayout 객체( windowLayout, QGraphicsLinearLayout )를 인스턴스화합니다. 또한 부모가 windowLayout 인 또 다른 객체( linear)를 인스턴스화합니다. 다음으로, LayoutItem 객체( item )를 생성하고 addItem() 함수를 사용하여 이를 linear 에 추가합니다. 또한 item 에 stretchFactor 를 제공합니다.

    QGraphicsLinearLayout *windowLayout = new QGraphicsLinearLayout(Qt::Vertical);
    QGraphicsLinearLayout *linear = new QGraphicsLinearLayout(windowLayout);
    LayoutItem *item = new LayoutItem;
    linear->addItem(item);
    linear->setStretchFactor(item, 1);

이 과정을 반복합니다:

  • 새로운 LayoutItem 를 생성하고,
  • linear 항목을 추가하고,
  • 신축 계수를 지정합니다.
    item = new LayoutItem;
    linear->addItem(item);
    linear->setStretchFactor(item, 3);
    windowLayout->addItem(linear);

그런 다음 linear 를 windowLayout 에 추가하여, 두 개의 QGraphicsLinearLayout 객체를 중첩시킵니다. QGraphicsLinearLayout 외에도, 일부 셀이 다른 행으로 이어지는 4x3 그리드인 QGraphicsGridLayout 객체( grid)도 사용합니다.

아래 코드 스니펫에서 볼 수 있듯이, 7개의 LayoutItem 객체를 생성하고 addItem() 함수를 사용하여 grid 에 배치합니다:

    QGraphicsGridLayout *grid = new QGraphicsGridLayout(windowLayout);
    item = new LayoutItem;
    grid->addItem(item, 0, 0, 4, 1);
    item = new LayoutItem;
    item->setMaximumHeight(item->minimumHeight());
    grid->addItem(item, 0, 1, 2, 1, Qt::AlignVCenter);
    item = new LayoutItem;
    item->setMaximumHeight(item->minimumHeight());
    grid->addItem(item, 2, 1, 2, 1, Qt::AlignVCenter);
    item = new LayoutItem;
    grid->addItem(item, 0, 2);
    item = new LayoutItem;
    grid->addItem(item, 1, 2);
    item = new LayoutItem;
    grid->addItem(item, 2, 2);
    item = new LayoutItem;
    grid->addItem(item, 3, 2);
    windowLayout->addItem(grid);

grid 에 추가하는 첫 번째 항목은 왼쪽 상단 셀에 배치되며, 4행에 걸쳐 있습니다. 다음 두 항목은 두 번째 열에 배치되며, 두 행을 차지합니다. 각 항목의 ` maximumHeight()`와 ` minimumHeight()` 값은 동일하게 설정되어 수직으로 확장되지 않습니다. 그 결과, 이 항목들은 셀에 수직으로 완전히 들어맞지 않게 됩니다. 따라서 ` Qt::AlignVCenter`을 사용하여 셀의 중앙에 수직으로 정렬되도록 지정합니다.

마지막으로, grid 자체를 windowLayout 에 추가합니다. QGridLayout::addItem()와 달리, QGraphicsGridLayout::addItem()는 인자로 행(row)과 열(column)을 필요로 하며, 이를 통해 항목이 배치될 셀을 지정합니다. 또한, rowSpan 및 columnSpan 인자가 생략되면 기본값은 1로 설정됩니다.

생성하는 각 LayoutItem 에 대해 부모를 명시적으로 지정하지 않는다는 점에 유의하십시오. 이 모든 항목은 windowLayout 에 추가되기 때문입니다. 레이아웃에 항목을 추가하면, 해당 항목은 레이아웃이 설치된 위젯으로 자동으로 부모가 재설정됩니다.

    setLayout(windowLayout);
    setWindowTitle(tr("Basic Graphics Layouts Example"));

이제 grid 를 설정하고 windowLayout 에 추가했으므로, QGraphicsWidget::setLayout()를 사용하여 windowLayout 를 창 객체에 설치하고 창 제목을 설정합니다.

LayoutItem 클래스 정의

LayoutItem 클래스는 QGraphicsLayoutItem 및 QGraphicsItem 의 하위 클래스입니다. 이 클래스에는 생성자, 소멸자 및 몇 가지 필수 재구현 메서드가 있습니다. QGraphicsLayoutItem 를 상속받으므로 {QGraphicsLayoutItem::setGeometry()}{setGeometry()} 및 {QGraphicsLayoutItem::sizeHint()}{sizeHint()}를 재구현해야 합니다. 또한 QGraphicsItem 를 상속받으므로 {QGraphicsItem::boundingRect()}{boundingRect()} 및 {QGraphicsItem::paint()}{paint()}를 재구현해야 합니다.

class LayoutItem : public QGraphicsLayoutItem, public QGraphicsItem
{
public:
    LayoutItem(QGraphicsItem *parent = nullptr);

    // Inherited from QGraphicsLayoutItem
    void setGeometry(const QRectF &geom) override;
    QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override;

    // Inherited from QGraphicsItem
    QRectF boundingRect() const override;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;

private:
    QPixmap m_pix;
};

LayoutItem 클래스에는 QPixmap 의 비공개 인스턴스인 m_pix 도 있습니다.

LayoutItem 클래스 구현

LayoutItem 의 생성자에서 m_pix 가 인스턴스화되고, block.png 이미지가 그 안에 로드됩니다.

LayoutItem::LayoutItem(QGraphicsItem *parent)
    : QGraphicsLayoutItem(), QGraphicsItem(parent),
      m_pix(QPixmap(QLatin1String(":/images/block.png")))
{
    setGraphicsItem(this);
}

사용되지 않는 매개변수에 대한 컴파일러의 경고 메시지를 방지하기 위해 Q_UNUSED() 매크로를 사용합니다.

void LayoutItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                       QWidget *widget)
{
    Q_UNUSED(widget);
    Q_UNUSED(option);

    QRectF frame(QPointF(0, 0), geometry().size());
    const QSize pmSize = m_pix.size();
    QGradientStops stops;

paint() 함수의 기본 개념은 배경 사각형을 그린 다음 픽스맵 주위에 사각형을 그리는 것입니다.

    // paint a background rect (with gradient)
    QLinearGradient gradient(frame.topLeft(), frame.topLeft() + QPointF(200,200));
    stops << QGradientStop(0.0, QColor(60, 60,  60));
    stops << QGradientStop(frame.height() / 2 / frame.height(), QColor(102, 176, 54));

    //stops << QGradientStop(((frame.height() + h)/2 )/frame.height(), QColor(157, 195,  55));
    stops << QGradientStop(1.0, QColor(215, 215, 215));
    gradient.setStops(stops);
    painter->setBrush(QBrush(gradient));
    painter->drawRoundedRect(frame, 10.0, 10.0);

    // paint a rect around the pixmap (with gradient)
    QPointF pixpos = frame.center() - (QPointF(pmSize.width(), pmSize.height()) / 2);
    QRectF innerFrame(pixpos, pmSize);
    innerFrame.adjust(-4, -4, 4, 4);
    gradient.setStart(innerFrame.topLeft());
    gradient.setFinalStop(innerFrame.bottomRight());
    stops.clear();
    stops << QGradientStop(0.0, QColor(215, 255, 200));
    stops << QGradientStop(0.5, QColor(102, 176, 54));
    stops << QGradientStop(1.0, QColor(0, 0,  0));
    gradient.setStops(stops);
    painter->setBrush(QBrush(gradient));
    painter->drawRoundedRect(innerFrame, 10.0, 10.0);
    painter->drawPixmap(pixpos, m_pix);
}

boundingRect()의 재구현은 왼쪽 상단 모서리를 (0,0)으로 설정하며, 그 크기는 레이아웃 항목 geometry()의 크기와 동일합니다. 이것이 우리가 그리는 영역입니다.

QRectF LayoutItem::boundingRect() const
{
    return QRectF(QPointF(0, 0), geometry().size());
}

setGeometry()의 재구현은 단순히 기본 클래스의 구현을 호출합니다. 하지만 이로 인해 boundingRect가 변경되므로 prepareGeometryChange()도 호출해야 합니다. 마지막으로, geom.topLeft() 에 따라 항목을 이동시킵니다.

void LayoutItem::setGeometry(const QRectF &geom)
{
    prepareGeometryChange();
    QGraphicsLayoutItem::setGeometry(geom);
    setPos(geom.topLeft());
}

아이템의 크기가 픽스맵보다 작아지지 않도록 하려면, m_pix 보다 큰 크기 힌트를 반환해야 합니다. 또한 나중에 그릴 테두리를 위해 주변에 여유 공간을 추가합니다. 또는 픽스맵보다 항목이 작아지지 않도록 픽스맵의 크기를 조정할 수도 있습니다. 권장 크기는 최소 크기 힌트와 동일하게 설정하고, 최대 크기는 큰 값으로 설정합니다.

QSizeF LayoutItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
    switch (which) {
    case Qt::MinimumSize:
    case Qt::PreferredSize:
        // Do not allow a size smaller than the pixmap with two frames around it.
        return m_pix.size() + QSize(12, 12);
    case Qt::MaximumSize:
        return QSizeF(1000,1000);
    default:
        break;
    }
    return constraint;
}

예제 프로젝트 @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.