Qt/C++ - Tutorial 077. QComboBox - ignoring hidden items in the drop-down list when scrolling

QComboBox, Qt, eventFilter

In one of the previous articles, it was shown how to hide some items in the QComboBox drop-down list so that the user could not select them. However, I did not pay attention to the fact that if the user hovers the mouse on the combo box itself and scrolls the mouse wheel, it can select this hidden menu item. Therefore, this behavior should be prohibited.

You can do this with the help of the mouse scrolling event scrolling within this combo box.

Depending on the structure of the program, you can do this in two ways:

  1. Inherit from the QComboBox class and override the method wheelEvent(QWheelEvent * event ).
  2. Inherit from the QObject class and override the method eventFilter(QObject* obj , QEvent * event )

By itself, the main code of the method will be similar in both cases, there will be different locations of this code. This will be determined by whether you need to create a QComboBox custom class or not.

With inheritance from QComboBox

When inheriting from QComboBox , we override the wheelEvent(QWheelEvent* event) method and check which of the lines are hidden. We will ignore all hidden lines at the event of the scratch and jump to the next available visible line.

void CustomComboBox::wheelEvent(QWheelEvent* event)
{
    int row = this->currentIndex();
    int count = this->count();
    QListView* dropdownList = static_cast<QListView*>(this->view());

    do
    {
        event->angleDelta().y() < 0 ? ++row : --row;
        if (row >= 0 && row < count && !dropdownList->isRowHidden(row))
        {
            this->setCurrentIndex(row);
            return;
        }
    }
    while (row >= 0 && row < count);
}

With the filter installed

If you do not want to create a custom QComboBox , but you need this functionality, then you can create a filter in that window (all widgets are inherited from QObject), where your QComboBox is installed.

To do this, we redefine the window method eventFilter(QObject* obj , QEvent * event ).

bool Widget::eventFilter(QObject* obj, QEvent *event)
{
    if (event->type() == QEvent::Wheel)
    {
        QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
        QComboBox* comboBox = static_cast<QComboBox*>(obj);

        int row = comboBox->currentIndex();
        int count = comboBox->count();
        QListView* dropdownList = static_cast<QListView*>(comboBox->view());

        do
        {
            wheelEvent->angleDelta().y() < 0 ? ++row : --row;
            if (row >= 0 && row < count && !dropdownList->isRowHidden(row))
            {
                comboBox->setCurrentIndex(row);
                return true;
            }
        }
        while (row >= 0 && row < count);

        return true;
    }

    return QObject::eventFilter(obj, event);
}

and install this filter on the target QComboBox

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->comboBox->installEventFilter(this); // Установим фильтр
}
Virtual hosting with 10 percent discount
Virtual hosting with 10 percent discount
EVILEG offers reliable hosting with a 10% discount for virtual hosting and 5% for VPS
Support the author Donate

Comments

Only authorized users can post comments.
Please, Log in or Sign up
D
Aug. 16, 2019, 11:58 a.m.
Damir

C++ - Тест 003. Условия и циклы

  • Result:92points,
  • Rating points8
D
Aug. 16, 2019, 11:46 a.m.
Damir

C++ - Test 005. Structures and Classes

  • Result:75points,
  • Rating points2
u
Aug. 14, 2019, 1:55 p.m.
unrealproro

C++ - Test 005. Structures and Classes

  • Result:83points,
  • Rating points4
Last comments
Aug. 19, 2019, 6:41 a.m.
Andrej Jankovich

это проблема дистрибутива, попробуйте установить через пакетный менеджер snap Суть проблемы: libQt5Core которая лежит в дистрибутиве требует версию glibc >= 2.25 у вас видимо …
b
Aug. 18, 2019, 5:09 a.m.
bbb116

cqtdeployer /home/aleks/CQtDeployer/bin/cqtdeployer: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by /home/aleks/CQtDeployer/lib/libQt5Core.so.5) linux mint …
D
Aug. 17, 2019, 8:04 a.m.
Damir

github ChekableTView Правой групповая смена значения при перетаскивании левой как обычно.
Aug. 16, 2019, 12:03 p.m.
Evgenij Legotskoj

Потому, что в минуте 60 секунд
Aug. 16, 2019, 11:16 a.m.
Dmitrij

а почему делитель 60000, а не 1000?
Now discuss on the forum
Aug. 19, 2019, 10:29 a.m.
Aleksej Vnukov

я в дороге, по тому примеру что в есть выше вам чтоб заработало нужно примерно следующее ListModel{ id: list_model } в ListView добавить model:list_model там где кноп…
Aug. 19, 2019, 8:47 a.m.
Pavel K.

bool YourClass::chekIfEmpty(const QString& table) { return getCount(table) == 0;}int YourClass::getCount(const QString& table, const QString& where) { QString command =…
Aug. 19, 2019, 8:29 a.m.
Pavel K.

посмотрите тут , практически тоже самое делал(пробегал по документу). А так в принципе : QFile file(Path);if(file.exist){ file.open(QIODevice::WriteOnly); // ReadWrite for…
Aug. 19, 2019, 2:39 a.m.
grig_p

Здравствуйте! Хотелось бы в своем приложении сделать цетрализованную обработку исключительных ситуаций для их логирования. Переопределил метод notify(): static const int EC_MAINLOOP…
Aug. 15, 2019, 2:19 a.m.
Mihailll

Плюсы и qml отличаются, с++ логичней
Looking for a Job?
14,000.00 руб. - 40,000.00 руб.
Разработчик Qt
Annino, Moscow Oblast, Russia
5,000.00 руб. - 15,000.00 руб.
Дизайнер
Moskovskiy, Moscow, Russia
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

For registered users on the site there is a minimum amount of advertising

EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB