How to change QPushButton icon/text spacing with stylesheets?
Asked Answered
C

7

8

I'm fairly new to Qt's method of stylesheets and I am looking to adjust the spacing between the icon and text on a QPushButton.

This is the gap I'm referring to: http://imageshack.us/scaled/thumb/593/4kem.png (stackoverflow won't let me post pics yet)

QPushButton {
   qproperty-icon: theme_url("/button_action/add");
   qproperty-iconSize: 14px; 
}

Is there a parameter I can use to adjust this space? I've tried margin, padding, spacing? Perhaps there is a different selector that I can use to just grab the icon?

Condense answered 27/6, 2013 at 14:17 Comment(4)
I haven't seen anything helpful in stylesheets, maybe you can just use whitespaces in button's text? ;)Alternative
There are a lot of buttons in the system so I was hoping to have a one stop answer rather than having to change them all manually...Condense
You could modify the icon to be wider to account for the gap? As far as I know there is no such style sheet property. You could just not set the text and icon at all on the button but instead set a layout on the button and insert 2 labels, 1 for the icon, one for the textHurds
Please, re-post the image. Link seems to be broken.Casaubon
E
3

Here's an opportunistic approach to customize the spacing between text and icon. There's currently no regular way to change the width, so we need to add a transparent area to the right of the icon which is applied to paint device.

Firstly, add a new member variable "m_spacing"(double) and initialize it to 0.0 in constructor, as a factor of expanding the width. Then, override the "paintEvent", "sizeHint" and "minimumSizeHint".

class CPushButton : public QPushButton {
    Q_OBJECT
public:
    double spaceRatio() const;
    void setSpaceRatio(double ratio);
protected:
    double m_spacing;
    void paintEvent(QPaintEvent *event) override;

......

QSize CPushButton::sizeHint() const {
    QSize sz = QPushButton::sizeHint();
    int offset = iconSize().width() * m_spacing;
    return QSize(sz.width() + offset, sz.height());
}

QSize CPushButton::minimumSizeHint() const {
    QSize sz = QPushButton::minimumSizeHint();
    int offset = iconSize().width() * m_spacing;
    return QSize(sz.width() + offset, sz.height());
}

void CPushButton::paintEvent(QPaintEvent *event) {
    QSize sz = iconSize();
    QPixmap tmp = icon().pixmap(sz); // Get the pixmap to apply with right size

    sz.rwidth() *= 1 + m_spacing;    // Multiply width

    QPixmap exp(sz);                 // Expended
    exp.fill(Qt::transparent);

    QPainter painter(&exp);
    painter.drawPixmap(QRect(QPoint(), tmp.size()), tmp);

    QStylePainter p(this);            // From Qt source
    QStyleOptionButton option;        // From Qt source
    initStyleOption(&option);         // From Qt source

    option.icon = QIcon(exp);         // Change to real icon
    option.iconSize = sz;             // Change to real size

    p.drawControl(QStyle::CE_PushButton, option); // From Qt source
    
    Q_UNUSED(event)
}

Now you can create a CPushButton instance and set the spacingRatio to 0.1 or other positive real. Visually, it does increase the spacing between text and icon.

Engagement answered 21/12, 2021 at 22:20 Comment(0)
C
2

Here is a workaround way to achieve that 'space between text and image':

QPushButton{
border:0px;
image: /*your url*/;
padding-top:16px;
image-position:top;

text-align:bottom;
padding-bottom:10px;
}

since qss doesn't support relative size, you need to implement resize() to change stylesheet when size changing to get a fixed space between text and image.

Cotta answered 8/3, 2021 at 10:32 Comment(0)
G
1

Actually with QPushButton you are out of luck. You can find a complete list of working options for styling push buttons in the qt documentation ( I am assuming you use qt5, but it is available for other versions as well).

What is often recommended if you want more control over the icon is to exchange your QPushButtons with QToolButtons wich are exactly the same except that they have extra features to make them compatible with toolbars -and- they have more options for icon placement. But this might not work for you because as you can see they are styled the exact same way as QPushButtons. But do look into the "toolButtonStyle" parameter which allows you to move the icon around.

Next on the list comes changing the artwork. If all you want is more space then just add the extra empty pixels to the artwork. This really hurts the perfectionist's mind but is effective.

Next on the list comes subclassing QPushButton and overriding the paint yourself. Sounds more daunting than it is. Subclassing in Qt has become a habit already and it works great. Here is a tutorial i googled in a jiffie (for 4.8 but should be about the same for 5) on the matter of subclassing. It even covers overriding the paint event.

Hope this was helpful.

Godroon answered 30/7, 2014 at 19:40 Comment(1)
your last link is outdated. i know its from 2014Chilson
A
1

At least with Qt5.5 (this may change in the future, I hope), besides overriding the paint event, which is complex and in my opinion messy for just a simple thing, there's no inherent Qt way to move that icon a few pixels here or there (small adjustments). If you remove the icon and use a stylesheet to set the background to your icon in your resource URL, you can use background-position property in the stylesheet, but unfortunately it only accepts words like center, left, etc., not pixel adjustments.

Here's how I resolved this problem. I created transparent PNGs that were slightly larger than I needed, where I had like a 4px margin around the icon itself inside the PNG. Then, I just moved the icon inside that canvas and reloaded it into the project resources file, and then mapped it again with the icon property in the designer for the QPushButton, and that worked. I now have icons that line up properly on the left with the text beside it. I can even widen the gap between icon and text.

Aleman answered 2/10, 2015 at 19:50 Comment(0)
F
1

As of Qt5.7 I don't know of any built-in functionality for the icon/text spacing. What I usually do is give the image some more space to the right and set the icon size of the button accordingly.

Solution:

  1. Resize your icon file to 32*16 px but leave its content as is.
  2. Call setIconSize(QSize(32, 16)) on your button.

Result: Now there's 16 pixel empty space between its icon and text. 32 pixel is just my example, you can of course set the additional size to something that suites your style.

If you want to apply that on all your button elements simply create a tiny subclass that does it automatically in the constructor. There's really no need to override the paintEvent method for this.

Fy answered 17/8, 2016 at 14:25 Comment(0)
B
1

Best way to solve this problem is adding some blank space in the beginning of QPushButton text. it works well for me! See here

Bobcat answered 5/6, 2022 at 13:1 Comment(0)
P
0

The simplest way to go for it is to create your own class inheriting from the QPushButton and override the PaintEvent and then manually place the pixmap of the icon where ever you want.

Pyre answered 24/12, 2015 at 10:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.