0

我有一堆可检查的 QToolbuttons,我希望图标在未选中状态下“变灰”。我可以通过在 QIcon 中为开/关状态设置不同的文件来实现这一点。像这样:

    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 可以创建在禁用模式下使用的自身“灰色”版本,我更喜欢使用禁用模式图标而不是自己创建所有图标的灰色版本。这可能吗?

4

1 回答 1

0

您可以使用该状态获取灰色图标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子类并创建自定义静态函数,以根据您的需要获取首选图标(已设置模式)。

于 2022-02-04T00:20:39.177 回答