سؤال

The selection behavior is set to select rows, but only the hovered cell is highlighted. Is there any way to highlight the entire row?

هل كانت مفيدة؟

المحلول 2

There are 2 ways..

1) You can use delegates to draw the row background...
You will need to set the row to highlight in the delegate and based on that, do the highlighting.

2) Catch the signal of current row. Iterate over the items in that row and set background for each item.

Hope, It will usefull to you guys.

نصائح أخرى

First, you subclass QTableWidget/QTableView and reimplement mouseMoveEvent and leaveEvent.

In custom_table_widget.cpp, you should have:

...
CustomTableWidget::CustomTableWidget(QWidget *parent) :
  QTableWidget(parent)
{
  setMouseTracking(true);  // receives mouse move events even if no buttons are pressed.
}

void CustomTableWidget::mouseMoveEvent(QMouseEvent *event)
{
  // detect where the mouse cursor is relative to our custom table widget
  QModelIndex index = indexAt(event->pos());
  emit hoverIndexChanged(index);
}

void CustomTableWidget::leaveEvent(QEvent *event)
{
  // detect when the mouse cursor leaves our custom table widget
  emit leaveTableEvent();
  viewport()->update();
}
...

Next, you subclass QStyledItemDelegate. Reimplement paint method and add two slots to modify the hovered row. In row_hover_delegate.cpp, you should have:

...
void RowHoverDelegate::onHoverIndexChanged(const QModelIndex& item) {
  hovered_row_ = item.row();
}

void RowHoverDelegate::onLeaveTableEvent() {
  hovered_row_ = -1;
}

void RowHoverDelegate::paint(QPainter *painter,
                                  const QStyleOptionViewItem &option,
                                  const QModelIndex &index) const {
  QStyleOptionViewItem opt = option;
  if(index.row() == hovered_row_) {
    opt.state |= QStyle::State_MouseOver;
  } else {
    opt.state &= ~QStyle::State_MouseOver;
  }
  QStyledItemDelegate::paint(painter, opt, index);
}
...

Finally, connect the the signals/slots and set the item delegate:

connect(my_custom_table_widget, 
        &CustomTableWidget::hoverIndexChanged,
        my_row_hover_delegate,
        &RowHoverDelegate::onHoverIndexChanged);
connect(my_custom_table_widget, 
        &CustomTableWidget::leaveTableEvent,
        my_row_hover_delegate,
        &RowHoverDelegate::onLeaveTableEvent);

my_custom_table_widget->setItemDelegate(my_row_hover_delegate);

An old question but as I managed to solve it using only the delegate, here my solution for anybody stumbling across the same problem. This is in PyQt5, but should be easy to convert to c++.

class HoverDelegate(QStyledItemDelegate):

    def __init__(self, parent=None):
        super().__init__(parent)
        # Define the hover colour
        self.hoverBackground = QBrush(QColor('#F5F5F5'))
        # Initiate variables to invalid model indices
        self.currentHovered = QModelIndex()
        self.previousHovered = QModelIndex()

    def initStyleOption(self, option, modelIndex):
        super().initStyleOption(option, modelIndex)

        # Cache model indices
        if option.state & QStyle.State_MouseOver:
            if modelIndex.row() != self.currentHovered.row():
                self.previousHovered = self.currentHovered
                self.currentHovered = modelIndex

        # Set background brush if we're on a hover row
        if modelIndex.row() == self.currentHovered.row():
            option.backgroundBrush = self.hoverBackground


    def paint(self, painter, option, modelIndex):
        # Standard paint event takes care of painting the hover background
        # if defined in initStyleOption 
        super().paint(painter, option, modelIndex)

        # Remove the hover background from the previously hovered row
        # by requesting update of all cells of the previously hovered row
        if self.previousHovered.isValid():
            view = self.parent()
            col = 0
            index = self.previousHovered.siblingAtColumn(col)

            while index.isValid():
                view.update(index)
                col += 1
                index = index.siblingAtColumn(col)

            # Reset to an invalid index
            self.previousHovered = QModelIndex()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top