a.l.e
a.l.e

Reputation: 868

QComboBox: Only show the icons when expanded

Starting from a "normal" QCombobox

enter image description here

I'd like to get a QCombobox that only shows the icon when it's expanded, but not when it's collapsed.

enter image description here

I've found several answers to similar questions, but all of them show code for much more complex situations and I have not managed to distill the core of it.

There are two approaches I've seen: attaching a QListView or using a QItemDelegate (or both).

But I could not find any sample code that is straight to the point.

This is my starting point:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->iconsComboBox->addItem(QIcon(":/icons/1.png"), "red");
    ui->iconsComboBox->addItem(QIcon(":/icons/2.png"), "green");
    ui->iconsComboBox->addItem(QIcon(":/icons/3.png"), "pink");

    auto quitAction = new QAction();
    quitAction->setShortcuts(QKeySequence::Quit);
    addAction(quitAction);
    connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
}

The full working code at that stage is here: https://github.com/aoloe/cpp-qt-playground-qcombobox/tree/simple-qcombobox

How can I hide the icon when the QCombobox is closed?


I have accepted the two pull requests by eyllanesc:

You can get the code and run it to see it in action.

Upvotes: 5

Views: 1429

Answers (1)

eyllanesc
eyllanesc

Reputation: 244003

One possible solution is to override the paintEvent method:

##ifndef COMBOBOX_H
#define COMBOBOX_H

#include <QComboBox>
#include <QStylePainter>

class ComboBox : public QComboBox
{
public:
    using QComboBox::QComboBox;
protected:
    void paintEvent(QPaintEvent *)
    {
        QStylePainter painter(this);
        painter.setPen(palette().color(QPalette::Text));
        // draw the combobox frame, focusrect and selected etc.
        QStyleOptionComboBox opt;
        initStyleOption(&opt);
        opt.currentIcon = QIcon();
        opt.iconSize = QSize();
        painter.drawComplexControl(QStyle::CC_ComboBox, opt);
        // draw the icon and text
        painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
    }

};

#endif // COMBOBOX_H

and if you want to use it in the .ui then you must promote it.


Another possible solution is to use a QProxyStyle

#ifndef COMBOBOXPROXYSTYLE_H
#define COMBOBOXPROXYSTYLE_H

#include <QProxyStyle>

class ComboBoxProxyStyle : public QProxyStyle
{
public:
    using QProxyStyle::QProxyStyle;
    void drawControl(QStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const
    {
        if(element == QStyle::CE_ComboBoxLabel){
            if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
                QStyleOptionComboBox cb_tmp(*cb);
                cb_tmp.currentIcon = QIcon();
                cb_tmp.iconSize = QSize();
                QProxyStyle::drawControl(element, &cb_tmp, p, w);
                return;
            }
        }
        QProxyStyle::drawControl(element, opt, p, w);
    }
};

#endif // COMBOBOXPROXYSTYLE_H
ui->iconsComboBox->setStyle(new ComboBoxProxyStyle(ui->iconsComboBox->style()));

Upvotes: 4

Related Questions