如何在 QStyledItemDelegate 中绘制整行的背景?
Posted
技术标签:
【中文标题】如何在 QStyledItemDelegate 中绘制整行的背景?【英文标题】:How does one paint the entire row's background in a QStyledItemDelegate? 【发布时间】:2010-03-12 16:10:28 【问题描述】:我有一个 QTableView,我正在设置一个自定义 QStyledItemDelegate。
除了自定义项目绘画之外,我还想为选择/悬停状态设置行的背景颜色。我想要的外观类似于此 KGet 屏幕截图: KGet's Row Background http://www.binaryelysium.com/images/kget_background.jpeg
这是我的代码:
void MyDelegate::paint( QPainter* painter, const QStyleOptionViewItem& opt, const QModelIndex& index ) const
QBrush backBrush;
QColor foreColor;
bool hover = false;
if ( opt.state & QStyle::State_MouseOver )
backBrush = opt.palette.color( QPalette::Highlight ).light( 115 );
foreColor = opt.palette.color( QPalette::HighlightedText );
hover = true;
QStyleOptionViewItemV4 option(opt);
initStyleOption(&option, index);
painter->save();
const QStyle *style = option.widget ? option.widget->style() : QApplication::style();
const QWidget* widget = option.widget;
if( hover )
option.backgroundBrush = backBrush;
painter->save();
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);
painter->restore();
switch( index.column() )
case 0: // we want default behavior
style->drawControl(QStyle::CE_ItemViewItem, &option, painter, widget);
break;
case 1:
// some custom drawText
break;
case 2:
// draw a QStyleOptionProgressBar
break;
painter->restore();
结果是每个单独的单元格仅在鼠标悬停在其上时才会接收到 mousedover 背景,而不是整行。很难描述,所以这里是截图: The result of the above code http://www.binaryelysium.com/images/loader_bg.jpeg
在那张图片中,鼠标位于最左侧的单元格上,因此背景突出显示..但我希望将背景绘制在整行上。
我怎样才能做到这一点?
编辑:经过更多思考,我意识到 QStyle::State_MouseOver 状态仅被传递给鼠标所在的实际单元格,并且当为行 QStyle:: 中的其他单元格调用paint方法时State_MouseOver 未设置。
所以问题变成了是否存在 QStyle::State_MouseOver_Row 状态(答案:否),那么我该如何实现呢?
【问题讨论】:
也许我需要重新实现我的 qtableview,并覆盖paintevent? 【参考方案1】:当鼠标悬停在一行上时,您需要告诉视图更新其单元格,因此我建议在您的模型中进行跟踪。然后在绘制事件中,您可以使用自定义数据角色从模型索引中请求该数据。
【讨论】:
模型如何知道鼠标是否在一行上?这似乎严格属于视图? @Casey:您需要模型和视图之间的合作。当鼠标移过一行时,你可以告诉模型这样,然后模型需要告诉视图重绘必要的行,代理需要为你想要的画适当的背景。【参考方案2】:void TrackDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
QStyleOptionViewItem viewOption(option);
if (viewOption.state & QStyle::State_HasFocus)
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
QImage image(m_RowBackGroundImagePath);
QPixmap pixmap(m_RowBackGroundImagePath);
qDebug()<<"forward"<<pixmap.width()<<pixmap.height();
pixmap.scaled(option.rect.width(),option.rect.height());
qDebug()<<"back"<<pixmap.width()<<pixmap.height();
qDebug()<<option.rect.width()<<option.rect.height();
QBrush brush(pixmap);
painter->save();
painter->fillRect(option.rect, brush/*QColor(238, 233, 233, 255)*/);
painter->restore();
viewOption.rect = QRect(option.rect.x(), option.rect.y(), option.rect.width(), option.rect.height());
//viewOption.palette.setColor(QPalette::Text, QColor(Qt::red));
//viewOption.palette.setBrush ( QPalette::ButtonText, brush1);
QItemDelegate::paint(painter, viewOption,index);
int progress = index.model()->data(index,Qt::DisplayRole).toInt();
QStyleOptionProgressBar progressBarOption;
progressBarOption.rect = QRect(option.rect.x(), option.rect.y()+(SETHEIGHT - PROGRESSBARHEIGHT)/2, option.rect.width(), /*option.rect.height()*/PROGRESSBARHEIGHT);
//qDebug()<<progressBarOption.rect.x()<<progressBarOption.rect.y()<<progressBarOption.rect.height()<<progressBarOption.rect.width();
//qDebug()<<option.rect.x()<<option.rect.y()<<option.rect.height()<<option.rect.width();
progressBarOption.state |= QStyle::State_Enabled;
progressBarOption.direction = QApplication::layoutDirection();
progressBarOption.fontMetrics = QApplication::fontMetrics();
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.textAlignment = Qt::AlignCenter;
progressBarOption.textVisible = true;
progressBarOption.progress = progress < 0 ? 0 : progress;
progressBarOption.text = QString().sprintf("%d%%", progressBarOption.progress);
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);
break;
【讨论】:
你应该解释你的变化,大段代码很难“心理模拟”......以上是关于如何在 QStyledItemDelegate 中绘制整行的背景?的主要内容,如果未能解决你的问题,请参考以下文章
QStyledItemDelegate - updateEditorGeometry 如何工作?
QStyledItemDelegate中如何根据qStylesheet进行绘制
重新实现 QStyledItemDelegate::paint - 如何获取子元素坐标?
在带有 QSqlQueryModel 的 QListView 上使用 QStyledItemDelegate