Evgenii Legotckoi
Evgenii Legotckoi3 мая 2017 г. 12:23

Qt/C++ - Урок 064. Как скрыть элементы из выпадающего списка QComboBox

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

При попытке найти информацию в поисковых системах по этой теме в первую очередь натыкаешься на варианты, когда пытаются использовать кастомный делегат, наследованный от QItemDelegate , или попытки играться с флагами, которые можно установить элементам в QComboBox , но оба варианты не работают.

Первый вариант с QItemDelegate не будет работать потому, что если даже сделать так, что определённый элемент не будет отрисовываться, его место нахождения тем не менее будет в списке. Просто на этом месте будет пустой прямоугольник.

Второй вариант с флагами не подходит потому, что нет такого флага, который бы заставил QComboBox скрыть определённый элемент в списке, хотя наиболее близким по значению является флаг Qt::ItemIsEnabled , но если его сбросить, то тогда текст элемента становится серым, показывая, что элемент нельзя выбрать.

Ещё можно рассмотреть вариант с моделью данных и отрисовкой элементов, но мы опять же возвращаемся к QItemDelegate , который опять же не работает.


Что же тогда делать?

Взглянем на QComboBox с другой точки зрения.

Что это такое в самом простом варианте? - Это кнопка, по клику на которую появляется выпадающий список.

Что такое выпадающий список? - Это QFrame в который помещен объект, наследованный от QAbstractItemView. А если быть точным, то QListView.

В данном случае QListView будет содержать модель данных, из которой подставляется текущий выбранный элемент в QComboBox и эта же модель данных служит для отображения списка всех элементов. А сам QListView может !ВНИМАНИЕ! скрывать строки и при этом не удалять их из модели данных!!! И в данном случае в QComboBox может отображаться в качестве текущего элемента тот элемент, который можно скрыть из выпадающего списка. WIN!!!

Реализация

Для примера реализуем следующее приложение. Есть комбобокс с пятью элементами. Есть LineEdit, в который можно написать номер элемента, который можно скрыть. И есть кнопка, по нажатию которой, мы скрываем элемент в выпадающем списке. Для проверки можно выбрать какой-нибудь элемент и скрыть именно его из списка. Тогда Вы убедитесь, что он будет отображаться на QComboBox , но в выпадающем списке он не будет виден. (Номера элементов начинаются с 0)

Приложение будет выглядеть следующим образом.

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QComboBox>
#include <QPushButton>
#include <QLineEdit>
#include <QListView>

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void hideRow();

private:
    QComboBox *comboBox;  
    QPushButton *hideButton; // кнопка по клику которой будем скрывать заданный элемент
    QLineEdit *lineEdit;  // lineEdit, в который будем задавать элемент для скрытия
    QListView *listView; // указатель на список элементов
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"

#include <QGridLayout>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    comboBox(new QComboBox(this)),
    hideButton(new QPushButton("Hide", this)),
    lineEdit(new QLineEdit(this))
{
    QGridLayout *gridLayout = new QGridLayout(this);
    setLayout(gridLayout);
    gridLayout->addWidget(comboBox, 0, 0, 1, 2);
    gridLayout->addWidget(hideButton, 1, 0, 1, 1);
    gridLayout->addWidget(lineEdit, 1, 1, 1, 1);

    listView = new QListView(comboBox);
    comboBox->setView(listView);

    comboBox->addItem("0");
    comboBox->addItem("1");
    comboBox->addItem("2");
    comboBox->addItem("3");
    comboBox->addItem("4");

    connect(hideButton, &QPushButton::clicked, this, &Widget::hideRow);
}

Widget::~Widget()
{

}

void Widget::hideRow()
{
    listView->setRowHidden(lineEdit->text().toInt(), true);
}

Архив с проектом

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

Q
  • 24 декабря 2017 г. 18:16
  1. void Widget::hideRow()
  2. {
  3. qobject_cast<QListView *>(comboBox->view())->setRowHidden(lineEdit->text().toInt(), true);
  4. }
ВА
  • 7 августа 2018 г. 10:02

А как скрыть саму запись, без удаления строки из drop-down меню?

Evgenii Legotckoi
  • 8 августа 2018 г. 3:49

Что простите? Откуда именно Вы собрались скрывать запись? И ищ выпадающего спика она не удаляется, а скрывается.

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:50баллов,
  • Очки рейтинга-4
m
  • molni99
  • 26 октября 2024 г. 8:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80баллов,
  • Очки рейтинга4
m
  • molni99
  • 26 октября 2024 г. 8:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20баллов,
  • Очки рейтинга-10
Последние комментарии
ИМ
Игорь Максимов22 ноября 2024 г. 19:51
Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 октября 2024 г. 21:37
Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 октября 2024 г. 15:19
Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов5 октября 2024 г. 14:51
Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55 июля 2024 г. 18:02
QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Сейчас обсуждают на форуме
m
moogo22 ноября 2024 г. 15:17
Mosquito Spray System Effective Mosquito Systems for Backyard | Eco-Friendly Misting Control Device & Repellent Spray - Moogo ; Upgrade your backyard with our mosquito-repellent device! Our misters conce…
Evgenii Legotckoi
Evgenii Legotckoi24 июня 2024 г. 22:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey115 ноября 2024 г. 14:04
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProject4 июня 2022 г. 10:49
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…

Следите за нами в социальных сетях