Models和Views是在所有类型软件的设计模式中频繁出现的,为了使数据从Model中分离出来并通过View渲染为用户提供的模型,一个健壮并可重用的设计被创造了。
Models是用于描述数据结构的,List是一维的数据容器。Table也是一个List,只不过是多列的——一个二维的数据结构。Tree是一个简单的Table,只不过数据有可能隐藏在另外的一维数据里。
当你考虑如何建立程序时,你会发现这些结构能够用于所有情况,所以你能很好的建立代表你的数据结构的Model。要记住你不要改变的你实际存储的数据的方式,你可以提供一个Model类代表你的数据,然后映射每一项模型化的数据到你应用程序的数据结构中的实际项。
所有这些结构可以以多种不同的方式显示。例如,List可以是一个列表(所有的Item立即显示),也可以是下拉列表(只显示当前Item)。每一个value也可以以多种方式显示。例如,text,values,甚至images。这就是view送入图片的地方——它的任务就是显示用户模型里的数据。
在标准的 MVC 设计模式中,Model保存数据,View渲染成显示部件,当用户想编辑数据时,Controller类处理对数据的所有修改。
Qt对这种模式进行了稍微处理,使用Delegate类代替Controller类处理数据更新。Delegate有两个工作:帮助View渲染Value和帮助用户编辑Value。比较标准的MVC模式和Qt的方法,你可以说Controller和View合并了,只不过View用Delegates来处理Controller的工作。
用Views来显示Date
Qt 提供三个不同的View:tree,list,table.QListWidget类是QListView的特殊版本,QListWidget仅仅包括列表中的显示数据,然而QListView是从Model中访问它的数据。QListWidget有时因缺乏灵活性被认为是方便类,但是在不复杂的情形下与QListView和Model相比它更方便。
和List Widget与List View相关一样,QTreeWidget-QTreeView和QTableWidget-QTableView也是成对相关。
让我们通过一个例子来看看如何创建widgets.在下面的代码中你可以看到QTreeView,QListView,QTableView创建后被放入QSplitter.一个splitter是一个子部件之间可以移动的栏。就是用户可以自由地划分tree,list,table之间的空白。
1
2
3
4
5
6
7
|
QTreeView *view =
new
QTreeView;
QListView *list =
new
QListView;
QTableView *table =
new
QTableView;
QSplitter splitter;
splitter.addWidget( tree );
splitter.addWidget( list );
splitter.addWidget( table );
|
当widgets创建后,你必须创建并组装Model,开始时你要用到QStandardItemModel,Qt的一个标准Model。
下面的代码展示了model是如何组装的。组装过程包括三个循环:row(r),columns(c),和item(i)。循环创建了5行2列,其中第1列包括3个子项。
1
2
3
4
5
6
7
8
9
10
11
|
QStandardItemModel model( 5, 2 );
for
(
int
r=0; r<5; r++ )
for
(
int
c=0; c<2; c++)
{
QStandardItem *item =
new
QStandardItem( QString(
"Row:%1, Column:%2"
).arg(r).arg(c) );
if
( c == 0 )
for
(
int
i=0; i<3; i++ )
item->appendRow(
new
QStandardItem( QString(
"Item %1"
).arg(i) ) );
model.setItem(r, c, item);
}
|
让我们仔佃看看是如何组装的。首先,QStandardItemModel被创建,构造函数被指定为5行2列。然后通过循环创建每个Item,当c等于0时,使用appendRow添加3个子项. 最后,setItem使每个item放在合适的位置。
为Views设置Model:
1
2
3
|
tree->setModel( &model );
list->setModel( &model );
table->setModel( &model );
|
每个View都有Selection Model, 通过setSelectionModel(QItemSelectionModel*)方法设置。
通过下面的设置,tree, list, table将被绑在一起:list中被选中的,在table和tree中也会被选中。
1
2
|
list->setSelectionModel( tree->selectionModel() );
table->setSelectionModel( tree->selectionModel() );
|
Providing Headers:
1
2
|
model.setHorizontalHeaderItem( 0,
new
QStandardItem (
"Name"
));
model.setHorizontalHeaderItem( 1,
new
QStandardItem (
"Phone number"
));
|
Limiting Editing:
设置只读:
1
2
3
4
5
6
7
|
if
( c == 0 )
for
(
int
i=0; i<3; i++ )
{
QStandardItem *child =
new
QStandardItem( QString(
"Item %1"
).arg(i) );
child->setEditable(
false
);
item->appendRow( child );
}
|
Limiting Selection Behavior
The selection behavior can be set to SelectItems, SelectRows, or SelectColumns;
selection mode can be set to the following values:
• NoSelection: The user cannot make selections in the view.
• SingleSelection: The user can select a single item, row, or column in the view.
• ContiguousSelection: The user can select multiple items, rows, or columns in the view. The selection area must be in one piece, next to each other without any gaps.
• ExtendedSelection: The user can select multiple items, rows, or columns in the view. The selection areas are independent and can have gaps. The user can choose items by clicking and dragging, selecting items while pressing the Shift or Ctrl keys.
• MultiSelection: Equivalent to ExtendedSelection from the programmer’s viewpoint, the selection areas are independent and can have gaps. The user toggles the selected state by clicking the items. There is no need to use the Shift or Ctrl keys.
下面是单行的设置:
1
2
|
table->setSelectionBehavior( QAbstractItemView::SelectRows );
table->setSelectionMode( QAbstractItemView::SingleSelection );
|
Using the QStringListModel to populate a QListView:
1
2
3
4
5
6
|
QListView list;
QStringListModel model;
QStringList strings;
strings <<
"Huey"
<<
"Dewey"
<<
"Louie"
;
model.setStringList( strings );
list.setModel( &model );
|
创建定制视图:
There are two approaches to this: either build a delegate from the QAbstractItemDelegate class or create a completely custom view from the QAbstractItemView class.