QTableView/QTableWidget 实现hover一行效果
在网上看到一些实现这个效果都是通过鼠标事件判断悬浮在哪一行实现的,这里提供另一种思路。
在Qt的模型/视图/代理框架里面,关于item的绘制是交给代理实现的,默认的QStyledItemDelegate的paint会去调用
virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const;
这个虚函数,初始化一些绘制的背景/字体等参数,所以我们可以重写这个虚函数,在里面判断是否悬浮在该行,如果是,则改变option参数里背景/前景色为设置的颜色,以达到hover的效果
void DrawRowTableDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
{
QStyledItemDelegate::initStyleOption(option, index);
if(!m_drawHoverRowEnabled){
return ;
}
if(isHoveredRow(*option, index)){
option->backgroundBrush = m_hoveredRowBackground;
option->palette.setBrush(QPalette::Text, m_hoveredRowForeground);
option->palette.setBrush(QPalette::Active, QPalette::Highlight, m_hoveredRowBackground);
option->palette.setBrush(QPalette::Active, QPalette::HighlightedText, m_hoveredRowForeground);
}
}
bool DrawRowTableDelegate::isHoveredRow(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
bool ret = false;
int gridWidth = 0;
if(const QTableView* tableView = qobject_cast<const QTableView*>(option.widget)){
gridWidth = tableView->showGrid() ? 1 : 0;
}
for(int i = 0; i < index.model()->columnCount(); ++i){
QModelIndex idx = index.model()->index(index.row(), i);
if(const QAbstractItemView* view = qobject_cast<const QAbstractItemView*>(option.widget)){
QStyleOptionViewItem o;
o.initFrom(view);
o.rect = view->visualRect(idx).adjusted(0, 0, gridWidth, gridWidth);
if(o.rect.contains(view->viewport()->mapFromGlobal(QCursor::pos()))){
ret = true;
}
}
}
return ret;
}
效果如下
工程链接:HoverRowTableWidget