© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB

Qt/C++ - Урок 077. QComboBox - игнорирование скрытых пунктов в выпадающем списке при скроллинге

QComboBox, Qt, eventFilter

В одной из предыдущих статей было показано, как скрыть некоторые пункты в выпадающем списке QComboBox , чтобы пользователь не мог их выбрать. Однако я не обратил внимание на то, что если пользователь наведёт курсор мыши на сам комбобокс и прокрутит колёсико мышки, то он сможет выбрать данный скрытый пункт меню. Следовательно такое поведение следует запретить.

Сделать это можно с помощью перехвата события прокрутки колёсика мышки в рамках данного комбобокса.

В зависимости от структуры программы можно сделать это двумя способами:

  1. Наследоваться от класса QComboBox и переопределить метод wheelEvent(QWheelEvent * event ).
  2. Наследоваться от класса QObject и переопределить метод eventFilter(QObject* obj , QEvent * event )

Сам по себе основной код метода будет аналогичен в обоих случаях, будет различно местонахождения данного кода. Это будет определяться тем, требуется ли вам создавать кастомный класс QComboBox или нет.

С наследованием от QComboBox

При наследовании от QComboBox переопределим метод wheelEvent(QWheelEvent * event ) и будем проверять, какие из строк скрытые. Все скрытые строки при событии прокрытки будем игнорировать и перескакивать на следующую доступную видимую строку.

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);
}

С установкой фильтра

Если же вы не хотите создавать кастомный QComboBox , но вам требуется данный функционал, то вы можете создать фильтр в том окне (все виджеты наследованы от QObject ), где установлен ваш QComboBox.

Для этого переопределим у окна метод 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);
}

и установим этот фильтр на целевой QComboBox

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->comboBox->installEventFilter(this); // Установим фильтр
}

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
19 октября 2018 г. 8:05
Василий Ильченко

C++ - Тест 001. Первая программа и типы данных

  • Результат:66баллов,
  • Очки рейтинга-1
18 октября 2018 г. 16:14
druidx

C++ - Тест 002. Константы

  • Результат:25баллов,
  • Очки рейтинга-10
18 октября 2018 г. 15:58
druidx

C++ - Тест 001. Первая программа и типы данных

  • Результат:80баллов,
  • Очки рейтинга4
Последние комментарии
19 октября 2018 г. 7:59
Евгений Легоцкой

Python 3 - Урок 001. Введение

Добрый день! Вот это линуксовая директива #!/usr/bin/python3 Указывает, где находится python пакет в системе. А вы видимо под windows разрабатываете. Попробуйте просто у...
19 октября 2018 г. 7:54
Abdurashid Parpieff

Python 3 - Урок 001. Введение

Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. >>> #!/usr/bi...
18 октября 2018 г. 8:31
Евгений Легоцкой

Qt/C++ - Урок 006. QSqlQueryModel - Таблицы в Qt с помощью SQL-запросов

Как-то даже странно, а вы что ли в отдельный поток убрали базу данных? То есть изначально инстанс создаётся в одном потоке, а все QSqlQuery в другом потоке? Они должны находиться в одном поток...
17 октября 2018 г. 8:43
pasagir

Qt/C++ - Урок 006. QSqlQueryModel - Таблицы в Qt с помощью SQL-запросов

Не получается bool DataBase::insertDataIntoDB(QVariantList data){ QSqlQuery query(db); QString str; qDebug()<<"InsertInsertInsertInsertInsert"<<QThread::curre...
17 октября 2018 г. 7:09
Евгений Легоцкой

Qt/C++ - Урок 006. QSqlQueryModel - Таблицы в Qt с помощью SQL-запросов

Попробуйте передать инстанс базы данных в конструктор QSqlQuery QSqlQuery q(db);
Сейчас обсуждают на форуме
19 октября 2018 г. 11:52
Евгений Легоцкой

Уведомления о лайках и дислайках

Вообще планируется система ачивок. А рейтинг есть в зачаточном состоянии. Но для системы ачивок нужно собраться с духом и выделить приличную кучку времени. Помимо того, что сами ачивки п...
18 октября 2018 г. 12:15
Михаиллл

Настройка Qt Creator для Android

все галочки включены.
18 октября 2018 г. 8:16
Allyans .

Работа с WinAPI в QT(изменение title bar)

Хорошо, я попробуй по вашей статье.
15 октября 2018 г. 12:45
Allyans .

QGraphicsItem change color

Хорошо)
11 октября 2018 г. 10:13
Arrow

Работа с WebView в QML

Нашел в чем проблема. Пишу на случай если кому-то попадется такое же счастье с WebView как и мне. Проблема как оказалась с Debug версией, так как в Release и Profile все работает (...
Присоединяйтесь к нам в социальных сетях