Qt Model-View (1)

简介

Qt的Model-View框架是MVC设计模式的变形,主要是由Model和View组成,Model中包含数据,View负责将数据以某种方式呈现出来,如表格,树形以及列表形式。那么MVC设计模式中的Controller并非舍弃而是将Controller中一部分的功能添加到了View中,另一部分则是由Delegate完成,完整的Qt Model-View框架是由Model-View-Delegate构成。


Model-ViewFramework

Model与Data

在Model-View中数据Data存放在Item之中,Model包裹着Item,数据的组织形式可以是多总多样的,这要视具体的项目而定。通过查阅Qt文档,可以很容易的将Item放入Model中,而获取Item中的数据不是直接通过Model而是通过QModelIndex,可以在View,Delegate和seletionModel获取QModelIndex,QModelIndex不仅可以获得Item中的数据,而且可以获得包含该Item的Model,也就是说,QModelIndex是Item和Model的桥梁。


Model-QModelIndex-Item

选择与简单编辑

在PC客户端用户选择表中的数据,可以有多种选择方式,单选、多选、按住Shift或Ctrl键进行多选等,而选择是交由View完成的,通过设置View的selectionBehavior与selectionMode属性可以设定选择方式。

1.    SelectionBehavior

QAbstractItemView::SelectItems   只能选择一个Item

 QAbstractItemView::SelectRows   按整行进行选择

QAbstractItemView::SelectColumns   按整列进行选择

2.    SelectionMode

 QAbstractItemView::SingleSelection :只能选择单个Item,单个行或列

QAbstractItemView::ContiguousSelection :可以进行多选,但选择的元素,行或列必须连成一个整体,中间不可以有漏选。

QAbstractItemView::ExtendedSelection :可以进行多选,选择的元素之间可以有不被选择的元素,在选择的同时必须按住shift或者ctrl键。

QAbstractItemView::MultiSelection :同ContiguousSelection,只是不需要按住Shift或者Ctrl选择。

QAbstractItemView::NoSelection :Items不可以被选择。

通过Item设置setEditable(bool editable)可以设置Item是否可以进行修改,true表示可以修改,反之不可以修改。

自定义View

有两种方法可以自定义View,一种方法是新建一个继承于QAbstractItemDelegate的类,另一种方法是新建一个继承与QAbstractItemView的类。

表1到表2


表1与表2的区别是表二第二列使用了类似于进度条的形式展现数据。

在这里我选择使用新建一个继承于QAbstractItemDelegate的类BarDelegate,以下是该类的声明。

classBarDelegate:publicQAbstractItemDelegate
{
public:
   BarDelegate(QObject*parent=0);
   voidpaint(QPainter*painter,
               constQStyleOptionViewItem&option,
               constQModelIndex&index)const;
   QSizesizeHint(constQStyleOptionViewItem&option,
                   constQModelIndex&index)const;
};


sizeHint

该函数必须与paint函数一同实现,真正的大小是可以改变的,这里只是给一个不会超过尺寸限制的QSize并且也能够将Item包裹进去。

paint

该函数需要实现的功能就是绘图,这里绘制的矩形框的大小,是由option和index共同给定的,一方面,option给定当前包裹item矩形的大小,以及用户对View中Item的操作情况,也就是option.state,通过index的data()函数可以十分方便的获得Item中的数据,并将数据(这里是100以内的随机数)转换成矩形的长度。

关键代码如下:

voidBarDelegate::paint(QPainter*painter,constQStyleOptionViewItem&option,constQModelIndex&index)const
{
   if(option.state&QStyle::State_Selected)
   {
        painter->fillRect(option.rect,option.palette.highlight());
   }
 
   intvalue=index.data(Qt::DisplayRole).toInt();
   doublefactor=(double)value/100.0;
   painter->save();
   if(factor>1)
   {
        painter->setBrush(Qt::red);
        factor=1;
   }
   else
   {
        painter->setBrush(QColor(0,(int)(factor*255),255-(int)(factor*255)));
   }
 
   painter->setPen(Qt::black);
 
   painter->drawRect(option.rect.x()+2,option.rect.y()+2,
                      (int)(factor*(option.rect.width()-5)),
                      option.rect.height()-5);
   painter->restore();
}


猜你喜欢

转载自blog.csdn.net/sinat_23185975/article/details/54633537