The selection behavior is set to select rows, but only the hovered cell is highlighted. Is there any way to highlight the entire row?
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);
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.
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()
© 2022 - 2024 — McMap. All rights reserved.