QGraphicsItem 들 사이를 Parent-children 관계로 구성하기

이미 아는 얘기지만 Qt5에서는 다양한 QGraphicsItem들을 제공한다. 이러한 item 들은 개별적으로 사용할 수 도 있지만 좀 더 복잡한 item을 만들기 위해서는 parent-children 관계를 구성하여 새로운 QGraphicsItem을 만들 수 있다. 이 방법은 매우 유용하고 강력한 기능들을 제공한다.

1. Parent-children 관계 이해하기

아래 그림을 보면 Fruit이 parent이고 Apple, pear 등은 children 이다. C++에서 보면 클래스 상속의 개념이 parent-children 개념이다. Qt5도 기본적으로 C++언어를 사용하므로 클래스 상속 개념은 동일하게 적용된다. 그러면 이런 관계를 사용할 경우 어떤 이점이 있을까? 부모 클래스가 가지고 있는 모든 능력을 자식클래스가 동등하게 사용할 수 있다는 것이 가장 큰 장점이라 할 수 있다. 


즉 Fruit이 맛이 좋다면 Apple, pear 등의 맛도 좋다는 것이다. 그러나 자식클래스는 또한 자신만의 특징을 별도로 가질 수도 있다. Fruit 색이 하얀색이더라도 자식인 Apple은 빨간색을 가질 수 있다는 것이다. 

2. QGrahpicsItem에 적용해보기

QGrahpicsItem에 적용해보기 위해 기본 프로젝트를 하나 생성하고 QGrahpicsItem클래스를 상속할 클래스를 하나 추가한다. 본 과정의 상세 설명은 여기를 참조하자. QGrahpicsItem을 직접 상속하지 말고 QGrahpicsRectItem를 상속하도록 하자. 그러면 상속된 클래스의 선언부는 다음과 같이 될 것이다. 아래에서 보면 public 속성에 parent를 선언하였다.  여기서 parent가 될 변수이다.

pressurizer.h

#ifndef PRESSURIZER_H
#define PRESSURIZER_H

#include <QGraphicsRectItem>


class Pressurizer : public QGraphicsRectItem
{

public:
    Pressurizer(qreal x, qreal y, qreal width, qreal height);
    QGraphicsRectItem *parent;
private:
    qreal x;
    qreal y;
    qreal width;
    qreal height;
};

#endif // PRESSURIZER_H

위에서 상속된 클래스 이름은 Pressurizer 이다. 아래는 Pressurizer 클래스의 생성자함수이다.

pressurizer.cpp

#include "pressurizer.h"

Pressurizer::Pressurizer(qreal x, qreal y, qreal width, qreal height)
    :x(x), y(y), width(width), height(height)
{
    parent = new QGraphicsRectItem(x, y, width, height);
}

위에서 생성된 클래스를 main.cpp 파일에 아래와 같이 코딩하여 실행해보자.

main.cpp

#include "pressurizer.h"

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene;
    //
    Pressurizer *pzr = new Pressurizer(0,0,50,200);
    scene.addItem(pzr->parent);
    //
    QGraphicsView view(&scene);
    view.show();

    return a.exec();
}

위를 실행하면 아래와 같다.


이제 parent item에 children item을 연결해보자. 이 작업은 pressurizer.cpp에서 해준다. child가 추가된 Pressurizer 클래스의 생성자 함수는 다음과 같다.

#include "pressurizer.h"
#include <QBrush>

Pressurizer::Pressurizer(qreal x, qreal y, qreal width, qreal height)
    :x(x), y(y), width(width), height(height)
{
    // parent item
    parent = new QGraphicsRectItem(x, y, width, height);
    // Child items
    QGraphicsRectItem *child = new QGraphicsRectItem(x, 
                   y+0.5*height, width, 0.5*height, parent);
    QBrush childBrush = QBrush(QColor(Qt::blue));
    child->setBrush(childBrush);
}

위에서 보면 child item으로 사각형을 하나 만들었으며 생성할때 미리 만들어 둔 parent item과 연결하였다. 그리고 브러쉬를 사용하여 파란색으로 면을 색칠하였다. child item에서 주의할 점을 parent와 연결을 할 경우 parent item의 좌표를 따른다는 점이다. 위를 실행하면 다음과 같다.



3. 정리하기

QGraphicsItem 중 하나를 상속받아 parent-children 관계를 구현해보았다. 이는 매우 유용한 기술로 잘 이해해두어야 한다. 다음에는 본 프로젝트에 QTimer 클래스를 이용하여 파란색 사각형이 위로 아래로 움직이도록 해보자.














댓글

이 블로그의 인기 게시물

SPACE 코드 제어 계통도를 그림 파일로 변환하는 예시

Scintilla 라이브러리를 활용한 SPACE 코드 전용 에디터 AESPA 개발 [2일차]