使用 Qicon 禁用模式关闭状态

Use Qicon disabled mode for off state

我有一堆可检查的 QToolbutton,我希望图标 'greyed out' 处于未检查状态。 我可以通过为 QIcon 中的 on/off 状态设置不同的文件来完成此操作。像这样:

    tb = QToolButton()
    tb.setCheckable(True)
    ico = QIcon()
    ico.addFile('color.jpg', QSize(16, 16), QIcon.Normal, QIcon.On)
    ico.addFile('grey.jpg', QSize(16, 16), QIcon.Normal, QIcon.Off)
    tb.setIcon(ico)

但是由于 QIcon 可以创建一个在禁用模式下使用的自身的 'greyed out' 版本,我更愿意使用禁用模式图标而不是自己创建所有图标的灰色版本。这可能吗?

您可以使用QIcon.pixmap()并使用Disabled状态获得灰色图标,然后再次设置为所需模式。

因为你想要它用于 Off 状态(默认),你必须首先为 On 状态设置像素图,获取灰色像素图,然后将其设置为其他状态:

    original = QtGui.QPixmap('icon.png')
    icon = QtGui.QIcon()
    icon.addPixmap(original, QtGui.QIcon.Normal, QtGui.QIcon.On)
    grayed = icon.pixmap(original.size(), QtGui.QIcon.Disabled, QtGui.QIcon.On)
    icon.addPixmap(grayed, QtGui.QIcon.Normal, QtGui.QIcon.Off)

请注意,虽然 Qt 的常见行为是使图像变灰,但不能保证它会发生在所有平台和样式上。

由于我们在谈论图标,我们可以假设它们非常小,因此我们可以使用辅助函数来获得变灰的像素图(同时仍然尊重 alpha 通道):

def getGrayed(src):
    if isinstance(src, QtGui.QPixmap):
        src = src.toImage()
    dest = QtGui.QImage(src.size(), QtGui.QImage.Format_ARGB32)
    widthRange = range(src.width())
    for y in range(src.height()):
        for x in widthRange:
            pixel = src.pixelColor(x, y)
            alpha = pixel.alpha()
            if alpha < 255:
                alpha //= 3
            gray = QtGui.qGray(src.pixel(x, y))
            pixel.setRgb(gray, gray, gray, alpha)
            dest.setPixelColor(x, y, pixel)
    return QtGui.QPixmap.fromImage(dest)

然后,做类似上面的事情:

    original = QtGui.QPixmap('iconalpha.png')
    icon = QtGui.QIcon(getGrayed(original))
    icon.addPixmap(original, QtGui.QIcon.Normal, QtGui.QIcon.On)

显然,如果有很多源图标并且它们的尺寸有点“大”(256x256 或更大),这可能会非常苛刻。
如果您担心性能问题,可以将上述 getGrayed() 函数转换为一个简单的脚本,该脚本会自动创建灰色图标。

请注意,如果您的代码中多次需要该功能,您可以考虑创建自己的 QIconEngine 子类并创建一个自定义静态函数来获取首选图标(已设置模式)根据您的需要。