(四)Paint函数实现QTableView中增加QCheckBox的方法

阅读更多

    第四种方法是:实现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

 

【Qt】QTableView中嵌入复选框CheckBox 的四种方法总结 

你可能感兴趣的:(QTableView,增加,QCheckBox,Qt)