Evgenii Legotckoi
April 23, 2018, 3:07 p.m.

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

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.

  1. void CustomComboBox::wheelEvent(QWheelEvent* event)
  2. {
  3. int row = this->currentIndex();
  4. int count = this->count();
  5. QListView* dropdownList = static_cast<QListView*>(this->view());
  6.  
  7. do
  8. {
  9. event->angleDelta().y() < 0 ? ++row : --row;
  10. if (row >= 0 && row < count && !dropdownList->isRowHidden(row))
  11. {
  12. this->setCurrentIndex(row);
  13. return;
  14. }
  15. }
  16. while (row >= 0 && row < count);
  17. }

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* ).

  1. bool Widget::eventFilter(QObject* obj, QEvent *event)
  2. {
  3. if (event->type() == QEvent::Wheel)
  4. {
  5. QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
  6. QComboBox* comboBox = static_cast<QComboBox*>(obj);
  7.  
  8. int row = comboBox->currentIndex();
  9. int count = comboBox->count();
  10. QListView* dropdownList = static_cast<QListView*>(comboBox->view());
  11.  
  12. do
  13. {
  14. wheelEvent->angleDelta().y() < 0 ? ++row : --row;
  15. if (row >= 0 && row < count && !dropdownList->isRowHidden(row))
  16. {
  17. comboBox->setCurrentIndex(row);
  18. return true;
  19. }
  20. }
  21. while (row >= 0 && row < count);
  22.  
  23. return true;
  24. }
  25.  
  26. return QObject::eventFilter(obj, event);
  27. }

and install this filter on the target QComboBox

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

By article asked0question(s)

3

Do you like it? Share on social networks!

P
  • March 19, 2020, 2:32 p.m.
  • (edited)

Здравствуйте, у меня есть вопрос по комбобоксу. Примеры из интернета со стилями не дают того, что нужно.

есть комбобокс. рядом кнопка по нажатии которой текущему элементу комбобокса устанавливается некий цвет.

  1. QComboBox * cb
  2. QColor color = QColorDialog::getColor( );
  3. cb->setItemData( cb->currentIndex(), QBrush( color ), Qt::BackgroundRole );

например второму элементу такой цвет

но при наведении мыши цвет перекрывается цыетом селектора. даже если ему затать прозразный цвет.

как можно решить это?

Evgenii Legotckoi
  • March 19, 2020, 4:35 p.m.
  • (edited)

Добрый день. Думаю, что нужно писать кастомный делегат. На форуме уже какие-то делегаты проскакивали, не помню только, для комбобоксов их делали или нет.
Но принцип похожий будет.

P
  • March 22, 2020, 2:48 a.m.
  • (edited)

вобщем решил проблему. может пригодится кому
без наследования, переопределений , делегатов и т.д ))
не знаю насколько правильно, но всё работает.
весь фокус - несколько строк кода.
можно задать любой цвет которым будет выделяться элемент при наведении.
если цвет брать из самого элемента на котором курсор, то получется , что выделение "как бы прозрачное"
только рамочка видна.

подключение к сигналу взял из примера в документации.
как соорудить стиль из цвета - наткнулся на просторах инета.

  1. connect(comboBox, QOverload<int>::of(&QComboBox::highlighted), [=](int index)
  2. {
  3. QColor color = ... // задаем нужный цвет. или берем цвет из элемента по индексу index
  4. QString style = "QComboBox QAbstractItemView { selection-background-color: rgb(%1, %2, %3); }" ;
  5. style = style.arg(color.red( )).arg(color.green( )).arg(color.blue( ) );
  6. comboBox->setStyleSheet(style);
  7. });

Comments

Only authorized users can post comments.
Please, Log in or Sign up
  • Last comments
  • AK
    April 1, 2025, 11:41 a.m.
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    March 9, 2025, 9:02 p.m.
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    March 9, 2025, 4:14 p.m.
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
  • ИМ
    Nov. 22, 2024, 9:51 p.m.
    Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
  • Evgenii Legotckoi
    Oct. 31, 2024, 11:37 p.m.
    Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup