如何防止 Qt 对 QListView 中的图标进行 alpha 混合选择?

Posted

技术标签:

【中文标题】如何防止 Qt 对 QListView 中的图标进行 alpha 混合选择?【英文标题】:How to prevent Qt from alpha-blending the selection over icons in QListView? 【发布时间】:2017-01-06 23:58:58 【问题描述】:

我有一个使用 QTableView 和 QListView 的 Qt 应用程序。在这两个小部件中,我都显示了一些图标。

问题在于,当用户选择其中一个条目时,Qt alpha 会将选择混合在图标上,从而使图标看起来对比度较低且颜色略有不同。

我希望 Qt 先绘制选择,然后在顶部绘制图标,这样无论它们是否被选中,它们看起来都一样。我该怎么做?

更新:

这就是我的问题的样子:

使用白色矩形图标更容易发现:

当您使用图形编辑器检查颜色值时,您会看到颜色值发生了变化。我希望 Qt 在没有此覆盖的情况下按原样绘制图标。

这里的 QListView 采用颜色渐变背景进行样式设置。但是我对没有样式的 QTableView 也有同样的问题。

顺便说一下,所有图标都是 SVG。

【问题讨论】:

我也有这个问题。您可以在 Qt Designer 中看到它,而无需任何样式表或自定义样式或任何东西 - 加载到 QIcon 的 Selected 状态的图标会得到修改的颜色。我尝试了修改后的列委托并交换了图标状态,只有 Selected 状态受到影响! 【参考方案1】:

ItemView 元素的绘制由委托处理。您可以为列、行或单个项目设置自定义委托。默认实现只是将绘图委托给小部件的样式:

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

    Q_ASSERT(index.isValid());

    QStyleOptionViewItem opt = option;
    initStyleOption(&opt, index);

    const QWidget *widget = QStyledItemDelegatePrivate::widget(option);
    QStyle *style = widget ? widget->style() : QApplication::style();
    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);

您可以找到绘制here 的实际代码。似乎 Qt5 附带的所有样式最终都会将 ItemView 元素的绘制委托给该代码。有趣的是,有问题的代码实际上在选择的顶部绘制了图标,因此您必须使用一些自定义样式。绘制选择的调用是:

proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget);

该调用先于所有其他绘图调用。

在您的自定义委托中,您应该能够通过修改QStyleOptionViewItem opt 来要求样式绘制除图标之外的所有内容(参见第一个代码 sn-p)。然后你可以手动绘制你的图标,就像QCommonStyle一样。

【讨论】:

【参考方案2】:

作为 IMO 更简单的替代解决方案,并且无论活动的 QStyle (需要进一步测试/确认)似乎都可以工作,您可以简单地继承 QIcon:

from PyQt5 import QtCore, QtGui

class StaticIcon(QtGui.QIcon):
    def __init__(self, filePath):
        super().__init__(filePath)
        self.addFile(filePath, QtCore.QSize(), QtGui.QIcon.Active)
        self.addFile(filePath, QtCore.QSize(), QtGui.QIcon.Selected)

...在样式自动设置后,用正常状态图标显式覆盖活动和选定状态图标。

【讨论】:

以上是关于如何防止 Qt 对 QListView 中的图标进行 alpha 混合选择?的主要内容,如果未能解决你的问题,请参考以下文章

QT4 qlistview保存图标位置手动移动下次

Qt入门系列开发教程高级控件篇QListview列表视图

如何从 QT 中的 QListView 获取所选项目的文本? [复制]

为啥 QListView 中看不到文件图标?

如何隐藏 Qt QListView 或 QListWidget 中的选择矩形/虚线?

Qt实现QQ好友下拉列表(用QListView实现,所以还得定义它的Model)