1

我在 QTableview 中使用的委托中有一个绘制方法,我在其中将复选框指示器添加到单元格。当我通过检查 QStyle::State_MouseOver 标志的 option.state 进入单元格时,很容易设置复选框的鼠标悬停状态,但理想情况下我需要做的只是在鼠标指针时为复选框指示器设置鼠标悬停状态位于指示器本身上方,而不仅仅是在单元格周围徘徊。不幸的是,目前仅在从一个单元格移动到另一个单元格时才会触发绘制方法,因此我需要一些有关如何执行此操作的指示。

代码如下(其中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);
}

任何帮助将非常感激。

4

2 回答 2

2

经过一番调查,我发现问题是我的 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;
}
于 2014-05-13T09:06:13.383 回答
1

更简单

bool hover = option.state & QStyle::State_MouseOver;
if (hover) {
    painter->fillRect(r, QColor(0,0,0,10));
}
于 2017-08-01T12:01:47.813 回答