Dynamically resize QIcon without calling setSizeIcon()

岁酱吖の 提交于 2019-12-02 05:15:36

Sub-classing QPushButton, as suggested by @Pavel in a comment, seems like a reasonable option to solve your issue. Below I provide a simple example that shows how this can be done in 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_())

Which results in:

The maximum size of the icon is limited by the size of the png used as input in QIcon. If a svg is used as input for the QIcon, the scaling of the icon won't be limited in size. However, svg icons seems not to be supported in Windows7, but they are in Ubuntu.

The code above would need to be expanded if a label is added to the button. Moreover, it would be possible to also scale the font size of the label to the button size if desired.

To persons who work in C++. Thanks a lot !

pushbuttoniconautoresize.h

#ifndef PUSHBUTTONIMAGEAUTOMATICRESIZE_H
#define PUSHBUTTONIMAGEAUTOMATICRESIZE_H

#include <QPushButton>

class PushButtonIconAutoResize : public QPushButton
{
    Q_OBJECT

public:
    PushButtonIconAutoResize(const QString &text, QWidget *parent=0);
    ~PushButtonIconAutoResize();

private:
    void paintEvent(QPaintEvent *event);

    int pad;
    int minSize;
};

#endif // PUSHBUTTONIMAGEAUTOMATICRESIZE_H

pushbuttoniconautoresize.cpp

#include "pushbuttoniconautoresize.h"

#include <QSize>
#include <QSizePolicy>
#include <QStylePainter>
#include <QStyleOptionButton>
#include <QtGlobal>

PushButtonIconAutoResize::PushButtonIconAutoResize(const QString &text, QWidget *parent)
    : QPushButton(text, parent)
{
    pad = 4;
    minSize = 8;

    this->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
}

PushButtonIconAutoResize::~PushButtonIconAutoResize()
{

}

void PushButtonIconAutoResize::paintEvent( QPaintEvent *event )
{
    QStylePainter painter(this);

    QStyleOptionButton opt;
    this->initStyleOption(&opt);

    QRect r = opt.rect;

    int h = r.height();
    int w = r.width();
    int iconSize = qMax(qMin(h, w) - 2 * this->pad, this->minSize);

    opt.iconSize = QSize(iconSize, iconSize);

    painter.drawControl(QStyle::CE_PushButton, opt);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!