PyQt: Windows Vista/7中QTableView的QStyledItemDelegate?

1 投票
2 回答
1936 浏览
提问于 2025-04-17 04:49

我想在一个 QTableView 中让某个单元格或行看起来像这样:

这里输入图片描述

在运行 Ubuntu 的时候,QStyledItemDelegateQTreeViewQTableView 上都能正常工作,但在 Windows 上,它只在 QTreeView 上有效,而且只有在我不重写 paint 方法的情况下。

所以我有两个问题:

我该如何让 QStyledItemDelegateQTableView 中看起来像上面的图片?

当我重写 paint 方法时,如何让 QStyledItemDelegate 也能看起来像上面的图片?

旁边的图片不是必须的。我只是想要那种样式的悬停和选中框。为了以防万一,我的 Qt 版本是 4.7.2。

2 个回答

1

我在qtcentre上开了个帖子,问了同样的问题。给我回复的那位朋友提供了一个用C++写的代码示例,还附上了一张结果的图片。看起来在C++中运行得很好,但在PySide中却不行(对pyQt的情况不太清楚),所以这可能是个bug。

这是可以正常工作的代码:

void ProgressBarDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
QStyledItemDelegate::paint(painter, option, index);

if( index.column() == 1 )
{
int progress = index.data().toInt();

QStyleOptionProgressBar progressBarOption;
progressBarOption.rect = option.rect;
progressBarOption.rect.setTop( option.rect.top() + 1 );
progressBarOption.rect.setHeight( option.rect.height() - 2 );
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.text = QString::number(progress) + "%";
progressBarOption.textVisible = true;
progressBarOption.textAlignment = Qt::AlignCenter;

QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);
}
}
1

我终于搞明白了一些事情。

我没有解决的问题是,为什么不重写 QStyledItemDelegate.paint() 的效果和重写它的效果不同:

def paint(self, painter, option, index):
    QStyledItemDelegate.paint(self, painter, option, index)

不过这其实不是我想问的内容。


我解决的问题是如何在手动绘制时获得原生的外观。之前在绘制项目时,我使用了:

QApplication.style().drawControl(QStyle.CE_ItemViewItem, option, painter)

但这样做的问题是没有绘制出原生的焦点或选中状态。我查看了 QApplication.style().drawControl() 的方法签名:

void QStyle::drawControl ( ControlElement element, const QStyleOption * option,
                           QPainter * painter, const QWidget * widget = 0 )

注意到有一个 widget 参数,于是我尝试传入一个 QTreeView。结果成功了。传入什么样的 QTreeView 都没关系,但这样做让视图以原生方式渲染。

所以最后,要在 QStyledItemDelegate 的绘制方法中简单地调用:

QApplication.style().drawControl(QStyle.CE_ItemViewItem, option, painter, QTreeView())

就可以实现原生的 QTableView 渲染。

撰写回答