본문

Qt Model/View 프로그래밍 #1. Model, View, Delegate


* 이 글에서는 item을 '개체'로 표현합니다.


데이터와 데이터의 표현을 위해 이들을 model과 view로 구분하여 관리할 수 있다. 이러한 구분을 통하여 개체(item)의 표현에 유연성을 부여하며, 다양한 데이터 원천(data source)에서 데이터를 로드하기 위한 표준화된 모델을 제공한다. 우리가 기존에 알고있던 MVC에서 view와 controller가 합쳐지게 되면 model/view 가 되는것이다. 이로서 MVC에서의 데이터와 표현의 분리에 대한 장점을 그대로 유지하면서 더 간단한 프레임워크를 제공할 수 있다. 사용자의 입력에 유연하게 대응하기 위하여 delegate라는 개념이 도입되었다. delegate의 장점으로 데이터의 각 개체가 표현되고 편집되는 방법을 커스터마이징 할 수 있다는 것이다.


model은 데이터의 원천과 연결되어 다른 컴포넌트들과의 상호작용을 위한 interface를 제공한다. 데이터의 원천과 연결되는 방법은 데이터 원천의 종류와 모델의 구현방법에 따라 달라질 수 있다. view는 model으로부터 model index를 받아온다. model index을 통하여 데이터의 각 개체에 대해 참조(reference)할 수 있으며, 이로서 데이터 원천상에 존재하는 데이터로부터 각 개체를 얻어올 수 있다. 표준 view에서, delegate는 데이터의 각 개체를 렌더링한다. 아이템이 편집되었을 경우 delegate는 model index를 통하여 모델과 직접 통신한다. 


즉, model/view 구조는 model, view, delegate로 나뉘어진다. 각각은 표준 인터페이스를 제공하는 추상클래스로서 정의된다. 추상클래스는 서브클래스화(subclass, 상속받아 구현한 클래스)되어, 다른 컴포넌트들이 요구하는 기능들을 제공할 수 있어야 한다. (역으로 이는 특별한 컴포넌트들이 작성될 수 있음을 의미한다)


또한, model, view, delegate는 signal과 slot을 사용하여 서로 통신을 한다. 

model에서 발생한 signal은 view에게 '데이터 원천에서의 데이터가 변경되었음'을 알려준다

view에서 발생한 signal은 보여지는 각 개체들에 대한 사용자의 활동사항을 알려준다.

delegate에서 발생한 slgnal은 편집 도중 발생함으로서, model과 view가 편집기의 상태를 알 수 있도록 한다.


* Model

모든 개체 model은 QAbstractItemModel 클래스에 기반한다. 이 클래스는 view와 delegate가 데이터에 접근할 수 있도록 인터페이스를 제공한다. 데이터 자체는 모델내에 저장될 필요는 없다(클래스, 파일, 데이터베이스 등에 데이터가 분리되어 저장될 수 있다) 이와 관련한 기본 개념은 Model Classes에 나와있다. 또한 이 클래스는 데이터와 연결되는 인터페이스를 제공함으로서, 테이블, 리스트, 트리에서 유연하게 표현될 수 있도록 해준다. 하지만 리스트나 테이블과같은 자료구조를 위한 새로운 model을 구현하고자 하는 경우, 공통적인 기능이 기본적으로 구현된 채로 제공하는 QAbstractListModel 또는 QAbstractTableModel 클래스를 사용하는 편이 더 낫다. 각 클래스들은 서브클래스화되어 특수한 종류의 리스트나 테이블을 위한 지원을 가능하게 한다. 이에 관해서는 Creating New Models을 참고한다.


Qt에는 각 경우에 대한 기본적인 model을 구현하여 제공하며, 이 표준 model들이 요구를 만족시키지 못할 경우 QAbstractItemModel, QAbstractListModel, QAbstractTableModel 를 서브클래싱하여 해결할 수 있다.

QStringListModel은 QString 개체에 대한 리스트에 적합하다.

QStandardItemModel은 복잡한 트리구조의 개체에 적합하며, 각각은 임의의(arbitrary) 데이터를 가질 수 있다. 리스트, 테이블, 트리 view를 위한 데이터 구조를 지원하는 다양한 용도를 위한 model이다. 

QFileSystemModel은 로컬 파일 시스템에서의 파일과 디렉토리에 대한 정보를 제공한다.

QSqlQueryModel, QSqlTableModel, QSqlRelationalTableModel 은 model/view의 개념으로 데이터베이스에 접근할 수 있도록 도와준다.


* View

다양한 view들에 대하여 다음과 같은 구현체들이 이미 존재하며 각각은 QAbstractItemView 추상클래스를 기반으로 하여 작성되었다. 이 클래스들은 수정없이 사용가능하지만 역시나 특정 용도를 위해 서브클래싱이 가능하다. 자세한 사항은 View Classes 페이지를 참고한다.

QListView는 개체의 목록(List)을 보여준다

QTableView는 model에서 받아온 데이터를 표의 형태(Table)로 보여준다.

QTreeView는 계층적인 목록(Tree)의 형태로 model상의 데이터를 보여준다


* Delegate

QAbstractItemDelegate가 delegate를 위한 기본추상클래스이다. Qt 4.4버전부터 QStyledItemDelegate로서 구현체가 제공되었고, 이는 Qt의 표준 view들에 대한 기본 delegate로서 사용되었다. QStyledItemDelegate와 QItemDelegate는 view상에서의 개체편집기를 표현하는 각기 다른 방법이며, 이때 QStyledItemDelegate는 현재 사용하고 있는 스타일을 그대로 유지하면서 기능을 제공한다는 점이 다르다. 따라서 QStyledItemDelegate의 서브클래싱이 권장된다. 자세한 사항은 Delegate Classes 페이지를 참고한다


* 제공되는 편리한 클래스들

표준 view 클래스로부터 파생된 여러 편리한 클래스들이 존재한다. 이들은 개체를 기반으로 하는 개체view와 테이블 클래스에 의존적이며, 서브클래스되도록 의도되진 않았으며 단지 Qt3에 있는 클래스들과 유사한 인터페이스를 제공하기 위해 존재한다. QListWidget, QTreeWidget, QTableWidget등이 있으며, 이들은 Qt3에서의 QListBox, QListView, QTable과 유사한 기능을 한다. 이 클래스들은 view클래스들보다 덜 유연하며 임의(arbitrary)의 데이터를 가지는 model과 함께 쓰일 수 없다. 개체기반의 클래스들만을 사용해야하는 환경이 아니라면 이것들을 사용하는 것 대신 model/view 구조를 사용하는것을 권장한다. 만약 개체기반의 인터페이스를 사용하는 동시에 model/view 의 장점을 활용하고자 한다면, QListView, QTableView, QTreeView와 같은 view 클래스와 QStandardItemModel을 사용하는것을 고려할 수 있다.


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

댓글

Holic Spirit :: Tistory Edition

design by tokiidesu. powerd by kakao.