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