본문

Qt Model/View 프로그래밍 #2. Model에 대하여

* Model 클래스의 개본 개념

model/view 구조에서 model은 view와 delegate가 데이터를 엑세스할 수 있도록 하는 표준 인터페이스를 제공한다. Qt에서는 QAbstractItemModel 클래스에 이 표준 인터페이스가 정의되어있다. 어떠한 자료구조로 데이터의 개체들이 저장되었든지간에 모든 QAbstarctItemModel의 서브클래스들은 데이터의 개체들을 계층적인 구조로 표현한다. view는 이러한 특성을 감안하여 모델에서 개체를 접근하지만, 사용자에게 표현하는 방법에 대해서는 제약받지 않는다. 또한, 모델은 연계된 view에게 signal/slot 메커니즘을 사용하여 데이터의 변경을 알린다.


* Model 인덱스

데이터의 표현방식과 데이터의 접근방식이 서로 관련이 없다는 사실은 'model 인덱스'라는 개념으로 더욱 공고해질 수 있다. view와 delegate는 인덱스를 사용하여 보여질 개체의 반환을 요청한다. 이를 통하여 model만이 데이터의 저장 방식에 대해 고려하며, model에 의해 관리되는 데이터의 타입은 보편적으로 정의될 수 있다. model 인덱스는 그것을 만든 model에 대한 포인터를 가지게 되며, 이것은 하나 이상의 model에서 작업할 때 혼동을 방지해준다. 

모델 index는 특정 정보에 대한 일시적인 참조위치(temporary reference)를 제공하며, model에서 데이터를 받아오거나 수정하는데 사용될 수 있다. model은 시간이 변함에 따라 데이터 내부구조를 지속적으로 재구성하기 때문에 model 인덱스는 무효화(invalid) 될 수 있으며, 따라서 변수에 저장되어 지속적으로 사용되기엔 적합하지 않다. 만약 특정 정보에 대한 장기간의 참조위치가 필요할 경우에는 참조위치를 항상 최신 위치로 유지하는, '지속적인(persistent) model 인덱스'가 생성되어야 한다. 일시적인 model 인덱스는 QModelIndex 클래스가 제공하며, 지속적인 model 인덱스는 QPersistentModelIndex가 제공한다.


* 행과 열로 접근하기

간단한 구조인 경우, model은 행과 열이 있는 간단한 표의 형태로 이해될 수 있다. (단, 이것은 데이터가 배열구조로 저장된다는것을 의미하진 않는다). 다음과 같이 행과 열으로 model 인덱스를 반환받고 이로서 model에서 원하는 정보를 반환받을 수 있다. QModelIndex index = model->index(row, column, ...);

리스트나 테이블과같은 간단한 자료구조를 가지는 model의 경우엔 부가적인 정보가 필요하지 않지만, 위의 코드가 암시하는바와같이 추가적인 정보를 model 인덱스에 제공해줄 수 있다. 위 그림은 각 개체가 행과 열로 표현되는 테이블을 나타낸다. model에서의 최상위 개체(root)는 언제든 QModelIndex()를 사용하여 참조될 수 있으며, 각 개체에 대한 참조(model 인덱스)는 아래와 같이 반환될 수 있다.

QModelIndex indexA = model->index(0, 0, QModelIndex());

QModelIndex indexB = model->index(1, 1, QModelIndex());

QModelIndex indexC = model->index(2, 1, QModelIndex());


* 개체의 부모



model에 표의 형태로 접근하는 방식은 테이블 혹은 리스트 view를 사용할때 가장 이상적이다. 하지만 트리와 같은 view에서는 하위에 있는 개체를 더욱 편리하게 접근할 수 있는 방법이 필요하였다. 따라서 각 개체는 또다른 개체들의 부모가 되는 방안이 마련되었다. model의 개체에 대한 참조위치(index)를 요청할 때, 개체의 부모에 대한 정보를 반드시 제공해야 한다. model과 분리된 상황에서 개체를 참조하는 유일한 방법은 model 인덱스를 통하는 것이기 떄문에 부모 인덱스는 반드시 제공되어야 한다. (즉 외부에서 처음 찾아들어갈 진입점을 제공한다는 의미) 따라서 다음과 같이 호출된다. QModelIndex index = model->index(row, column, parent); 이를 고려하여 각 개체의 인덱스는 다음과 같이 반환받을 수 있다. 또한 index의 부모에 잘못된 인덱스가 제시되었을 경우 해당 model의 최상위 개체의 인덱스가 반환된다.

QModelIndex indexA = model->index(0, 0, QModelIndex());

QModelIndex indexC = model->index(2, 1, QModelIndex());

QModelIndex indexB = model->index(1, 0, indexA);


* 개체의 역할



model에서의 각 개체는 여러 컴포넌트에서 다양한 역할을 수행할 수 있으며, 각기 다른 상황을 위해 다양한 데이터가 제공될 수 있다. 예를 들어, Qt::DisplayRole은 view에서 텍스트의 형태로 보여지게 될 문자열에 접근하는데 사용된다. 대부분의 경우, 개체는 (여러가지 역할을 수행할 다양할) 데이터를 가지며, 이에 대한 표준 역할은 Qt::ItemDataRole에서 정의되어 있다. 다음 코드와 같이 model에 model 인덱스와 더불어 원하는 데이터 타입을 지정하는 방식으로, 원하는 데이터에 접근할 수 있다. QVariant value = model->data(index, role); => QString text = model->data(index, Qt::DisplayRole).toString();


원문출처 : http://qt-project.org/doc/qt-5.0/model-view-programming.html

댓글

Holic Spirit :: Tistory Edition

design by tokiidesu. powerd by kakao.