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