4

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.

a.l.e
  • 792
  • 8
  • 16
  • The most similar question I've found, is probably [Hide Icon from the label of QComboBox](https://stackoverflow.com/questions/45546155/hide-icon-from-the-label-of-qcombobox), but the question is a bit vague and the only answer is not really encouraging (and points to a dead link). – a.l.e Nov 19 '19 at 09:54

1 Answers1

4

One possible solution is to override the paintEvent method:

##ifndef COMBOBOX_H
#define COMBOBOX_H

#include &ltQComboBox>
#include &ltQStylePainter>

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()));
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • thanks @eyllanesc for your answer. i'm not sure that this is the simplest solution. i'm currently exploring the usage of `QItemDelegate` and will later try to use a custom `ComboBox` as you suggest and come back and tell how it worked out. – a.l.e Nov 19 '19 at 10:49
  • 1
    @a.l.e I have made a PR to your repo so you can easily test it. The QItemDelegate only serves to modify the popup that clearly will not solve your problem. – eyllanesc Nov 19 '19 at 10:51