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:
- Inherit from the QComboBox class and override the method wheelEvent(QWheelEvent event* ).
- 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); // Установим фильтр }
Здравствуйте, у меня есть вопрос по комбобоксу. Примеры из интернета со стилями не дают того, что нужно.
есть комбобокс. рядом кнопка по нажатии которой текущему элементу комбобокса устанавливается некий цвет.
например второму элементу такой цвет
но при наведении мыши цвет перекрывается цыетом селектора. даже если ему затать прозразный цвет.
как можно решить это?
Добрый день. Думаю, что нужно писать кастомный делегат. На форуме уже какие-то делегаты проскакивали, не помню только, для комбобоксов их делали или нет.
Но принцип похожий будет.
вобщем решил проблему. может пригодится кому
без наследования, переопределений , делегатов и т.д ))
не знаю насколько правильно, но всё работает.
весь фокус - несколько строк кода.
можно задать любой цвет которым будет выделяться элемент при наведении.
если цвет брать из самого элемента на котором курсор, то получется , что выделение "как бы прозрачное"
только рамочка видна.
подключение к сигналу взял из примера в документации.
как соорудить стиль из цвета - наткнулся на просторах инета.