Реклама

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

Qt, QComboBox, QListView

В некоторых случаях требуется скрыть некоторые элементы из выпадающего списка 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);
}

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

Реклама

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
  • leha
  • 20 октября 2017 г. 11:38

Qt - Тест 001. Сигналы и слоты

  • Результат 63 баллов
  • Очки рейтинга -1
  • faust
  • 19 октября 2017 г. 18:53

C++ - Тест 005. Структуры и Классы

  • Результат 100 баллов
  • Очки рейтинга 10
  • faust
  • 19 октября 2017 г. 15:49

C++ - Тест 002. Константы

  • Результат 91 баллов
  • Очки рейтинга 8
Последние комментарии
  • EVILEG
  • 21 октября 2017 г. 3:06

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

Добавил архив с проектом

  • EVILEG
  • 20 октября 2017 г. 20:06

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

После работы поищу, должен где-то быть на винте.

  • Миша
  • 20 октября 2017 г. 20:04

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

не могли бы вы выложить архив с рабочей версией скрипта?

  • EVILEG
  • 20 октября 2017 г. 20:03

Qt/C++ - Урок 030. QCustomPlot - быстрый старт в работе с графиками

Использование дизайнера в Qt Creator и использование ui файлов является распространённой практикой в Qt фреймворке. Написать отдельную статью про то, что это такое? - может быть. Опи...

  • Миша
  • 20 октября 2017 г. 19:43

Qt/C++ - Урок 030. QCustomPlot - быстрый старт в работе с графиками

Но почему вы это не описали? Не могли бы вы описать.

Сейчас обсуждают на форуме
  • cordsac
  • 19 октября 2017 г. 15:49

How can I select the QGraphicView Item and change the properties

Ok I'll check it sir,If you can please do article(tutorial) about this,Its really useful.Thank you if you can give me some sample code when you free.thanks again

  • cordsac
  • 17 октября 2017 г. 19:28

How can I open SVG file through QT

Okay,Thank you sir :)

  • EVILEG
  • 16 октября 2017 г. 20:34

Qt, Загрузка изображения в QImage

Сам view нужно поместить в внутри окна, а не просто создать его. Можете создать в графическом редакторе Qt Creator`а окно, набросать там QGraphicsView и потом посмотреть в сгенерированном...

  • mihenze
  • 15 октября 2017 г. 21:30

Рисуем линию QGraphicsItem за мышью

Большое спасибо!

  • EVILEG
  • 15 октября 2017 г. 18:58

Описание класса С++ в QtCreator

Для начала добавьте недостающие методы и участники для Q_PROPERTY. Для этого вызовите контекстное меню через ПКМ у Q_PROPERTY, там будет пункт "добавить недостающие члены". Автоматически...