在不调用 setSizeIcon() 的情况下动态调整 QIcon 的大小

rba*_*dar 4 c++ qt svg pyqt4 autoresize

我目前正在努力解决什么应该很容易解决的问题。许多小部件支持某种QSizePolicy。这包括QPushbutton。在我的情况下,我在网格布局中有多个按钮,所有这些按钮的 QSizePolicy垂直和水平调整大小都设置为expand。这导致根据网格布局所属的小部件的大小调整按钮大小的 nead 结果。

问题来自 Qt 中图标的处理方式。QIcon 没有 QSizePolicy 属性(或者至少我无法在 Qt4 的官方文档中找到关于QIconQAbstractButton 的属性)。唯一的方法似乎是使用setIconSize(),您可以在其中提供图标的最大大小。此外,必须手动实施关于如何更新大小的例程。在这种情况下,它将是(这里抽象写作)icon.size == button.size-CONSTANT,其中 CONSTANT 是某种预定义的因子(> = 0)。为所选图标预定义各种尺寸(QIcons 列表)也是可能的,但仍然不是一个好的选择(请阅读下面的原因)。

这似乎有点矫枉过正,特别是因为 QPushbutton 支持 QSizePolicy 并且开发人员根本不必修补这个部门,除非他/她想要一些特殊的调整大小。这也与QIcon对 SVG 文件的支持相矛盾,因为众所周知,SVG = 矢量图形 = 您可以随意拉伸这些文件而不会降低质量。

有没有人知道一种简单的方法来做到这一点,而无需添加额外的偶数句柄来调整大小,提供所选图标的比例列表或将大小限制为最大大小?

PS:我也研究过 QPixmap - 那里仍然存在同样的问题。

编辑: 我忘了提一个方式,我发现了如何做我想要的(结果却不如漂亮,我希望他们是) -使用图像在样式表属性QPushbutton。但是,这不会创建图标!如果一个人真的不需要一个真正的图标并且可以使用这个属性来使用一个绘制的按钮,那么在调整大小方面会有很大的灵活性,尤其是在使用 SVG 时。

Jea*_*ien 5

QPushButton正如@Pavel 在评论中所建议的那样,子分类似乎是解决您的问题的合理选择。下面我提供了一个简单的例子,展示了如何在PySide.

import sys
from PySide import QtGui, QtCore

class myContainter(QtGui.QWidget):
    def __init__(self, parent=None):
        super(myContainter, self).__init__(parent)

        icon = QtGui.QIcon('process-stop.png')

        grid = QtGui.QGridLayout()

        for i in range(3):
            button = myPushButton()
            button.setIcon(icon) 

            grid.addWidget(button, i, 0)

            grid.setRowStretch(i, i)

        self.setLayout(grid)


class myPushButton(QtGui.QPushButton):
    def __init__(self, label=None, parent=None):
        super(myPushButton, self).__init__(label, parent)

        self.pad = 4     # padding between the icon and the button frame
        self.minSize = 8 # minimum size of the icon

        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                                       QtGui.QSizePolicy.Expanding)
        self.setSizePolicy(sizePolicy)

    def paintEvent(self, event):

        qp = QtGui.QPainter()
        qp.begin(self)

        #---- get default style ----

        opt = QtGui.QStyleOptionButton()
        self.initStyleOption(opt)

        #---- scale icon to button size ----

        Rect = opt.rect

        h = Rect.height()
        w = Rect.width()
        iconSize = max(min(h, w) - 2 * self.pad, self.minSize)

        opt.iconSize = QtCore.QSize(iconSize, iconSize)

        #---- draw button ----

        self.style().drawControl(QtGui.QStyle.CE_PushButton, opt, qp, self)

        qp.end()

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)

    instance = myContainter()  
    instance.show()    

    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

结果是:

在此处输入图片说明

图标的最大大小受 中png用作输入的大小的限制QIcon。如果 asvg用作 的输入QIcon,则图标的缩放将不受大小限制。然而,svg 图标似乎不支持在 Windows7 中,但它们在 Ubuntu 中。

如果将标签添加到按钮,则需要展开上面的代码。此外,如果需要,还可以将标签的字体大小缩放到按钮大小。

  • @rbaleksandar 坦率地说,您的问题使用了太多词:P。本来可以更简洁,直奔主题。感谢您提供有关使用 `resizeEvent` 的意见。我仍然更喜欢在 `paintEvent` 中处理它,如果超越简单的图标缩放,它会提供更多的灵活性。 (2认同)