Search code examples
c++qtqt5qcombobox

How to know when down-arrow of Combo box is clicked?


I have a ComboBox and set it to be edited.

QComboBox *myCombo = new QComboBox(this);
myCombo->setEditable(true);
myCombo->setStyleSheet("QComboBox::down-arrow{image: url(:/bulb.png);}");
myCombo->setCursor( QCursor( Qt::PointingHandCursor ) );

enter image description here

So now when i click onto the editing field, nothing happen. But what I need is, when I click onto the bulb (which is the down-arrow), something (like a table or a dialog....) should be appeared. How can I recognize this click event in this case? I looked at the list of signals for combo box but could not find any signal for that.


Solution

  • By overwriting the mousePressEvent() method you must use hitTestComplexControl() method to know that QStyle::SubControl has been pressed by issuing a signal if it is QStyle::SC_ComboBoxArrow.

    #include <QtWidgets>
    
    class ComboBox: public QComboBox
    {
        Q_OBJECT
    public:
        using QComboBox::QComboBox;
    signals:
        void clicked();
    protected:
        void mousePressEvent(QMouseEvent *event) override{
            QComboBox::mousePressEvent(event);
            QStyleOptionComboBox opt;
            initStyleOption(&opt);
            QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, event->pos(), this);
            if(sc == QStyle::SC_ComboBoxArrow)
                emit clicked();
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        ComboBox w;
        w.setEditable(true);
        w.setStyleSheet("QComboBox::down-arrow{image: url(:/bulb.png);}");
        QObject::connect(&w, &ComboBox::clicked, [](){
            qDebug()<<"clicked";
        });
        w.show();
        return a.exec();
    }
    #include "main.moc"
    

    Although showPopup() is a possible option this can be called directly without the down-arrow being pressed, for example by calling it directly: myCombo->showPopup() so it is not the correct option.