I have a paint method in a delegate used in a QTableview where I add a checkbox indicator to a cell. Its very easy to set the mouseover state of the checkbox when I enter the cell by checking the option.state for the QStyle::State_MouseOver flag but what I ideally need to do is only set the mouseover state for the checkbox indicator when the mouse pointer is over the indicator itself and not just hovering around the cell. Unfortunately the paint method is only triggered when moving from one cell to the other at present so I need some pointers on how to do this.

Code is as follows (where mouse_pointer_ is the last stored mouse coordinates):

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);
}

Any help would be much appreciated.

有帮助吗?

解决方案

After some investigation I found that the issue was that my editorEvent() method needed to return true (indicating that the cell contents have changed) to force the repaint of the cell and thus set the selected state. Code is below:

 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;
}

其他提示

more simple

bool hover = option.state & QStyle::State_MouseOver;
if (hover) {
    painter->fillRect(r, QColor(0,0,0,10));
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top