用法:
pView->setItemDelegateForColumn( 1, new DELEGATE::CheckBoxDelegate( this ) );
CheckBoxDelegate.h
#ifndef CHECKBOXDELEGATE_H
#define CHECKBOXDELEGATE_H
#include <QStyledItemDelegate>
#include <QModelIndex>
namespace DELEGATE
{
class CheckBoxDelegate
: public QStyledItemDelegate
{
Q_OBJECT
public:
CheckBoxDelegate( QObject *parent );
~CheckBoxDelegate();
void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
bool editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index );
private:
QModelIndex m_lastClickedIndex;
};
}
#endif // CHECKBOXDELEGATE_H
CheckBoxDelegate.cpp
#include "CheckBoxDelegate.h"
#include <QApplication>
#include <QStyleOptionButton>
#include <QPainter>
#include <QEvent>
#include <QMouseEvent>
namespace DELEGATE
{
CheckBoxDelegate::CheckBoxDelegate( QObject *parent )
: QStyledItemDelegate( parent )
{
}
CheckBoxDelegate::~CheckBoxDelegate()
{
}
void CheckBoxDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
// Setting parameters
Qt::CheckState state = (Qt::CheckState)index.data( Qt::CheckStateRole ).toInt();
QStyleOptionButton opt;
opt.state = QStyle::State_Enabled; // CheckBox enabled
if ( option.state & QStyle::State_MouseOver )
opt.state |= QStyle::State_MouseOver; // Mouse over sell
switch ( state ) // Check box 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;
}
// Check box rect
opt.rect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &opt, NULL );
const int x = option.rect.center().x() - opt.rect.width() / 2;
const int y = option.rect.center().y() - opt.rect.height() / 2;
opt.rect.moveTo( x, y );
// Optional: draw hover focus
if ( option.state & QStyle::State_MouseOver )
painter->fillRect( option.rect, QBrush( QColor( 0xff, 0xff, 0xaa, 0x60 ) ) );
// Mandatory: drawing check box
QApplication::style()->drawControl( QStyle::CE_CheckBox, &opt, painter );
}
bool CheckBoxDelegate::editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index )
{
switch ( event->type() )
{
case QEvent::MouseButtonPress:
m_lastClickedIndex = index;
break;
case QEvent::MouseButtonRelease:
{
if ( index != m_lastClickedIndex )
break;
QMouseEvent *e = static_cast< QMouseEvent * >( event );
if ( e->button() != Qt::LeftButton )
break;
m_lastClickedIndex = QModelIndex();
QStyleOptionButton opt;
opt.rect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &opt, NULL );
const int x = option.rect.center().x() - opt.rect.width() / 2;
const int y = option.rect.center().y() - opt.rect.height() / 2;
opt.rect.moveTo( x, y );
if ( opt.rect.contains( e->pos() ) )
{
// TODO: process click on checkbox logic
Qt::CheckState state = (Qt::CheckState)index.data( Qt::CheckStateRole ).toInt();
switch ( state )
{
case Qt::Unchecked:
state = Qt::PartiallyChecked;
break;
case Qt::PartiallyChecked:
state = Qt::Checked;
break;
case Qt::Checked:
state = Qt::Unchecked;
break;
}
model->setData( index, state, Qt::CheckStateRole );
}
return true;
}
default:
break;
}
return QAbstractItemDelegate::editorEvent( event, model, option, index );
}
}
示例:
需要改进的地方:
- 选择图
- 鼠标悬停处理
- 双击处理
- 键盘编辑事件//google、stackoverflow中有很多例子
注意:你的模型应该为 Qt::CheckStateRole 角色处理 setData 方法。