最近一直在使用Qt中的Model / View 进行编程。
首先介绍一下 Model / View的使用,参考http://doc.trolltech.com/4.2/model-view-programming.html
The model/view architecture The model communicates with a source of data, providing an interface for the other components in the architecture. The nature of the communication depends on the type of data source, and the way the model is implemented. The view obtains model indexes from the model; these are references to items of data. By supplying model indexes to the model, the view can retrieve items of data from the data source. In standard views, a delegate renders the items of data. When an item is edited, the delegate communicates with the model directly using model indexes. |
有图中我们可以知道,其实这个MVC模式差不多,model进行数据的访问与处理,view提供显示,而delegate则负责进行item的render,并且在Qt中,已经为我们提供了很多写好的常用class,使得我们能够很好的拿来使用。如 QAbstractListModel, QDirModel, QListView, QTreeView, QItemDelegate。而在使用的时候,如下
1 Create a existing model
QDirModel *model = new QDirModel;
2 Create the list view
QListView *list = new QListView(…);
3 Display the item
list->setModel(model);
1 Create a existing model
QDirModel *model = new QDirModel;
2 Create the list view
QListView *list = new QListView(…);
3 Display the item
list->setModel(model);
至于与delegate的关联,我们可以用list->setItemDelegate(new QItemDelegate());
在QListView中,如果我们要使用一个check box,我们可以直接在model类中data函数处理
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const
{
if(role == Qt::CheckStateRole)
{
return true;
}
.......
}
这样在QListView中就可以显示出勾选的check box,但是如果需要进行radio button的显示,我们还需要进行一些相关处理。
在QItemDelegate中,有一个drawCheck函数
virtual void drawCheck ( QPainter * painter, const QStyleOptionViewItem & option, const QRect & rect, Qt::CheckState state ) const
{
if (!rect.isValid())
return;
QStyleOptionViewItem opt(option);
opt.rect = rect;
opt.state = opt.state & ~QStyle::State_HasFocus;
switch (state) {
case Qt::Unchecked:
opt.state |= QStyle::State_Off;
break;
case Qt::PartiallyChecked:
opt.state |= QStyle::State_NoChange;
break;
case Qt::Checked:
opt.state |= QStyle::State_On;
break;
}
QApplication::style()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter);
}
该函数实现了check box的绘制,对于qt来说,check box与radio button在某些方面来说是一样的,只是在各自的样式上面的有点不一样,也就是对于style的绘制不一样,于是参考qt中QStyle类,使用QStyle::PE_IndeicatorRadioButton进行重新绘制,就可以变成radio button样式
QApplication::style()->drawPrimitive(QStyle::PE_IndicatorRadioButton, &opt, painter);
于是我们重写一个drawRadio函数,与drawCheck一样,就是最后一句使用上面处理。
然后我们重写delegate相关paint函数,
void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
QRect checkSpace; //the rect for draw check
int isCheck = index.model()->data(index, Qt::CheckStateRole).toInt(); //get the index item's check state
if(isCheck)
drawRadio(painter, option, checkSpace, Qt::Checked);
else
drawRadio(painter, option, checkSpace, Qt::Unchecked);
... ... //draw others like display role, decroration role
}
这样就能狗绘制一个radio button, 这是我目前发现的一种方法,不知道还有没其他办法。
至于check box与radio button怎么处理,参考qt相关开源代码就可以了,以后如果有时间在补上。