Evgenii Legotckoi
Evgenii Legotckoi03 травня 2017 р. 12:23

Qt/C++ - Урок 064. Як приховати елементи зі спадного списку QComboBox

У деяких випадках потрібно приховати деякі елементи зі списку QComboBox . Наприклад, користувачеві дається можливість вибрати один з декількох варіантів у QComboBox , але за замовчуванням повинен відображатися невалідний варіант, який повинен бути відсутнім у списку, що випадає. Тобто за замовчуванням вибрано щось неправильне, що при валідації буде перевірено і видасть користувачеві повідомлення, що потрібно вибрати один із можливих варіантів, які доступні, тоді як неправильний варіант відсутній у списку.

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

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

Другий варіант із прапорами не підходить тому, що немає такого прапора, який змусив би QComboBox приховати певний елемент у списку, хоча найбільш близьким за значенням є прапор Qt::ItemIsEnabled , але якщо його скинути, то тоді текст елемента стає сірим, показуючи, що вибрати елемент не можна.

Ще можна розглянути варіант з моделлю даних та відмальовуванням елементів, але ми знову ж таки повертаємося до QItemDelegate , який знову ж таки не працює.


Що ж тоді робити?

Поглянемо на QComboBox з іншого погляду.

Що це таке в найпростішому варіанті? - Це кнопка, на кліку на яку з'являється список, що випадає.

** Що таке список, що випадає?

В даному випадку QListView буде містити модель даних, з якої підставляється поточний вибраний елемент QComboBox і ця ж модель даних служить для відображення списку всіх елементів. А сам QListView може !УВАГА! приховувати рядки і при цьому не видаляти їх із моделі даних! І в даному випадку в QComboBox може відображатися як поточний елемент той елемент, який можна приховати з списку. WIN!!!

Реалізація

Наприклад реалізуємо наступне додаток. Є комбобокс із п'ятьма елементами. Є LineEdit, у якому можна написати номер елемента, який можна приховати. І є кнопка, за натисканням якої, ми приховуємо елемент у списку, що випадає. Для перевірки можна вибрати якийсь елемент і приховати саме його зі списку. Тоді Ви переконаєтеся, що він буде відображатися на QComboBox , але у списку, що випадає, він не буде видно. (Номери елементів починаються з 0)

Програма буде виглядати так.

віджет.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. }
ВА
  • 07 серпня 2018 р. 10:02

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

Evgenii Legotckoi
  • 08 серпня 2018 р. 03:49

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

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
Дмитрий

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

  • Результат:60бали,
  • Рейтинг балів-1
Дмитрий

C++ - Тест 003. Условия и циклы

  • Результат:92бали,
  • Рейтинг балів8
d
  • dsfs
  • 26 квітня 2024 р. 11:56

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

  • Результат:80бали,
  • Рейтинг балів4
Останні коментарі
k
kmssr09 лютого 2024 р. 02:43
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко05 лютого 2024 р. 09:50
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 грудня 2023 р. 18:30
Boost - статичне зв&#39;язування в проекті CMake під Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 грудня 2023 р. 16:38
Boost - статичне зв&#39;язування в проекті CMake під Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 грудня 2023 р. 05:01
Qt/C++ - Урок 056. Підключення бібліотеки Boost в Qt для компіляторів MinGW і MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Тепер обговоріть на форумі
G
George1307 травня 2024 р. 07:27
добавить qlineseries в функции в функции: "GPlotter::addSeries(QString title, QVector &arr)" я вызываю метод setChart(...), я в конструктор передал адрес на QChartView элемент
BlinCT
BlinCT05 травня 2024 р. 12:46
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
PS
Peter Son04 травня 2024 р. 00:57
Best Indian Food Restaurant In Cincinnati OH Ready to embark on a gastronomic journey like no other? Join us at App india restaurant and discover why we're renowned as the Best Indian Food Restaurant In Cincinnati OH . Whether y…
Evgenii Legotckoi
Evgenii Legotckoi02 травня 2024 р. 21:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 квітня 2024 р. 11:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…

Слідкуйте за нами в соціальних мережах