Qt委托设置鼠标悬停状态为复选框

时间:2014-05-09 12:46:36

标签: c++ qt qt4 qtableview qstyleditemdelegate

我在QTableview中使用的委托中有一个paint方法,我在其中向单元格添加一个复选框指示符。通过检查QStyle :: State_MouseOver标志的option.state进入单元格时,很容易设置复选框的鼠标悬停状态,但理想情况下我需要做的只是当鼠标指针设置复选框指示器的鼠标悬停状态超过指标本身而不只是在细胞周围盘旋。不幸的是,paint方法只在当前从一个单元格移动到另一个单元格时触发,所以我需要一些关于如何执行此操作的指针。

代码如下(其中mouse_pointer_是最后存储的鼠标坐标):

void
CheckBoxDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
                            const QModelIndex& index) const
{

   // Draw our checkbox indicator
   bool value = index.data(Qt::DisplayRole).toBool();
   QStyleOptionButton checkbox_indicator;

   // Set our button state to enabled
   checkbox_indicator.state |= QStyle::State_Enabled;
   checkbox_indicator.state |= (value) ? QStyle::State_On : QStyle::State_Off;

   // Get our dimensions
   checkbox_indicator.rect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkbox_indicator, NULL );

   // Position our indicator
   const int x = option.rect.center().x() - checkbox_indicator.rect.width() / 2;
   const int y = option.rect.center().y() - checkbox_indicator.rect.height() / 2;

   checkbox_indicator.rect.moveTo(x, y);

   if (checkbox_indicator.rect.contains(mouse_position_)) {
      checkbox_indicator.state |= QStyle::State_MouseOver; 
   }

   QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkbox_indicator, painter);
}

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

经过一些调查后我发现问题是我的editorEvent()方法需要返回true(表示单元格内容已经改变)以强制重新绘制单元格,从而设置所选状态。代码如下:

 bool CheckBoxDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
 {
    bool repaint_cell = false;  

    QMouseEvent *e = static_cast<QMouseEvent *> (event);

    mouse_position_ = e->pos();

    // We need to check if the mouse pointer is hovering within 
    // the checkbox indicator area of the table cell
    QStyleOptionButton checkbox_indicator;  
    checkbox_indicator.rect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &checkbox_indicator, NULL );
    const int x = option.rect.center().x() - checkbox_indicator.rect.width() / 2;
    const int y = option.rect.center().y() - checkbox_indicator.rect.height() / 2;
    checkbox_indicator.rect.moveTo(x, y );

    if (checkbox_indicator.rect.contains(mouse_position_)) {
        repaint_cell  = true;   

        // Check if the user has clicked in this area
        if (e->button() == Qt::LeftButton) {    

            switch(event->type()) {
                case QEvent::MouseButtonRelease: 
                    // Update model data in here
                    break;
                default:
                    break;
            }
        }

    }

    return repaint_cell;
}

答案 1 :(得分:0)

更简单

bool hover = option.state & QStyle::State_MouseOver;
if (hover) {
    painter->fillRect(r, QColor(0,0,0,10));
}