第四种方法是:实现QAbstractItemDelegate的paint()函数。
这种方法和《C++_GUI_Qt4_编程(第二版)》中第十章的自定义委托例子,画星星的作法是一样的,都是通过 QApplication::style()->drawControl(QStyle::CE_CheckBox,&check_box_style_option,painter);这个函数,只不过选择的元素是QCheckBox的。
使用Delegate Paint()函数 具体如下:
void QLineDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,const QModelIndex& index)const { bool checked = index.model()->data(index, Qt::DisplayRole).toBool(); if(index.column() == 0) { QStyleOptionButton check_box_style_option; check_box_style_option.state |= QStyle::State_Enabled; if(checked) { check_box_style_option.state |= QStyle::State_On; } else { check_box_style_option.state |= QStyle::State_Off; } check_box_style_option.rect = CheckBoxRect(option); QApplication::style()->drawControl(QStyle::CE_CheckBox,&check_box_style_option,painter); } QStyledItemDelegate::paint(painter,option,index); QStyleOptionViewItem itemOption(option); if(itemOption.state & QStyle::State_HasFocus) itemOption.state = itemOption.state ^ QStyle::State_HasFocus; QStyledItemDelegate::paint(painter,itemOption,index); QPen oldPen = painter->pen(); painter->setPen(pen); painter->drawLine(option.rect.topRight(),option.rect.bottomRight()); painter->drawLine(itemOption.rect.bottomLeft(),itemOption.rect.bottomRight()); painter->setPen(oldPen); }
完整的源代码如下:
class QLineDelegate : public QStyledItemDelegate { Q_OBJECT public: QLineDelegate(QTableView* tableView); protected: void paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index) const; bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) ; private: QPen pen; QTableView* view; }; static QRect CheckBoxRect(const QStyleOptionViewItem &view_item_style_options) { QStyleOptionButton check_box_style_option; QRect check_box_rect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &check_box_style_option); QPoint check_box_point(view_item_style_options.rect.x() + view_item_style_options.rect.width() / 2 - check_box_rect.width() / 2, view_item_style_options.rect.y() + view_item_style_options.rect.height() / 2 - check_box_rect.height() / 2); return QRect(check_box_point, check_box_rect.size()); } QLineDelegate::QLineDelegate(QTableView* tableView) { int gridHint = tableView->style()->styleHint(QStyle::SH_Table_GridLineColor, new QStyleOptionViewItemV4()); QColor gridColor = static_cast(gridHint); pen = QPen(gridColor,0,tableView->gridStyle()); view = tableView; } void QLineDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,const QModelIndex& index)const { bool checked = index.model()->data(index, Qt::DisplayRole).toBool(); if(index.column() == 0) { QStyleOptionButton check_box_style_option; check_box_style_option.state |= QStyle::State_Enabled; if(checked) { check_box_style_option.state |= QStyle::State_On; } else { check_box_style_option.state |= QStyle::State_Off; } check_box_style_option.rect = CheckBoxRect(option); QApplication::style()->drawControl(QStyle::CE_CheckBox,&check_box_style_option,painter); } QStyledItemDelegate::paint(painter,option,index); QStyleOptionViewItem itemOption(option); if(itemOption.state & QStyle::State_HasFocus) itemOption.state = itemOption.state ^ QStyle::State_HasFocus; QStyledItemDelegate::paint(painter,itemOption,index); QPen oldPen = painter->pen(); painter->setPen(pen); painter->drawLine(option.rect.topRight(),option.rect.bottomRight()); painter->drawLine(itemOption.rect.bottomLeft(),itemOption.rect.bottomRight()); painter->setPen(oldPen); } bool QLineDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { if((event->type() == QEvent::MouseButtonRelease) || (event->type() == QEvent::MouseButtonDblClick)) { QMouseEvent *mouse_event = static_cast (event); if(mouse_event->button() != Qt::LeftButton || !CheckBoxRect(option).contains(mouse_event->pos())) { return false; } if(event->type() == QEvent::MouseButtonDblClick) { return true; } } else if(event->type() == QEvent::KeyPress) { if(static_cast (event)->key() != Qt::Key_Space && static_cast (event)->key() != Qt::Key_Select) { return false; } } else { return false; } bool checked = index.model()->data(index, Qt::DisplayRole).toBool(); return model->setData(index, !checked, Qt::EditRole); }
不过有一个小问题,CheckBox旁边有false/true或其它字符的原因是:你的Model中的data返回值,应该排除这列。
转:http://www.cppblog.com/gaimor/archive/2011/11/26/160993.html