IscanderChe
IscanderChe22 січня 2019 р. 08:45

QSqlTableModel + QTableView + кастомный делегат в виде чекбокса

Qt, QSqlTableModel, QTableView

Всем добрый день.

Суть задачи: надо, чтобы в одной из колонок QTableView вместо хранимого в QSqlTableModel значения выводился чекбокс и при смене состояния чекбокса значения в базе тоже менялось. С помощью ItemIsUserCheckable проблему удалось решить.

Есть ли вариант решения с помощью кастомного делегата? У меня получается только частично: чекбокс виден только при щелчке на ячейку, данные исправно меняет, но при переходе к другой ячейке чекбокс заменяется данными.

class CheckBoxDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    CheckBoxDelegate(QObject* parent = 0);

    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,
                          const QModelIndex& index) const override;

    void setEditorData(QWidget* editor, const QModelIndex& index) const override;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override;

    void updateEditorGeometry(QWidget *editor,
            const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
QWidget* CheckBoxDelegate::createEditor(QWidget* parent,
    const QStyleOptionViewItem& option,
    const QModelIndex& index) const
{
    if(index.column() == 1)
    {
        QCheckBox* editor = new QCheckBox(parent);
        return editor;
    }

    return QStyledItemDelegate::createEditor(parent, option, index);
}

void CheckBoxDelegate::setEditorData(QWidget* editor,
    const QModelIndex& index) const
{
    if(index.column() == 1)
    {
        int value = index.model()->data(index, Qt::EditRole).toBool();
        QCheckBox* checkBox = static_cast<QCheckBox*>(editor);
        checkBox->setChecked(value != 0);
    }
}

void CheckBoxDelegate::setModelData(QWidget* editor,
    QAbstractItemModel* model, const QModelIndex& index) const
{
    if(index.column() == 1)
    {
        QCheckBox* checkBox = static_cast<QCheckBox*>(editor);
        bool value = checkBox->isChecked();
        model->setData(index, value, Qt::EditRole);
    }
}

void CheckBoxDelegate::updateEditorGeometry(QWidget* editor,
    const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    editor->setGeometry(option.rect);
}
Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

9
Evgenii Legotckoi
  • 23 січня 2019 р. 15:44
  • (відредаговано)

Добрый день! Про ваш вопрос помню, вынужден немного отложить, работы много. Чуть позже гляну кое-какие рабочие исходники с делегатами, нечто подобное уже реализовывал.

    IscanderChe
    • 15 лютого 2019 р. 16:22

    Доброй ночи.
    Скромно напоминаю о своём вопросе...

      Evgenii Legotckoi
      • 17 лютого 2019 р. 12:28

      Добрый день. Очень извиняюсь за долгий ответ

      Первое, что нашёл, так это необходимость перерисовать чекбокс.

      void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
      {
          if (index.column() == 1)
          {
              painter->save();
              bool checked = index.model()->data(index, Qt::DisplayRole).toBool();
      
              QStyleOptionButton check_box_style_option;
              check_box_style_option.state |= QStyle::State_Enabled;
              if (checked) {
                  check_box_style_option.state |= QStyle::State_On;
              } else {
                  check_box_style_option.state |= QStyle::State_Off;
              }
              check_box_style_option.rect = option.rect;
      
              QApplication::style()->drawControl(QStyle::CE_CheckBox, &check_box_style_option, painter);
              painter->restore();
              return;
          }
      
          QStyledItemDelegate::paint(painter, option, index);
      }
      
        IscanderChe
        • 19 лютого 2019 р. 01:51

        Да, теперь чекбокс виден постоянно. Но для того, чтобы изменить его состояние, прежде нужно выделить ячейку с ним. Это как-то лечится?

          Evgenii Legotckoi
          • 19 лютого 2019 р. 03:34

          Попробуйте включить все триггеры редактирования

          yourView->setEditTriggers(QAbstractItemView::AllEditTriggers)
          
            IscanderChe
            • 19 лютого 2019 р. 07:03

            Тот же эффект.

              Evgenii Legotckoi
              • 20 лютого 2019 р. 09:40

              Думаю, что ещё можно переопределить mouseReleaseEvent(QMouseEvent* event) у QTableView, который содержит модель и немного поиграться с индексом. Если это индекс, который соответствует колонке с чекбоксом, то изменить значение принудительно не дожидаясь перехода ячейки в режим редактирования.

                IscanderChe
                • 20 червня 2019 р. 05:30

                Вернулся к этой задачке только-только, поэтому и не ответил ничего раньше.
                Как переопределить mouseReleaseEvent(QMouseEvent* event) у QTableView, если QTableView задан в ui? Или задавать QTableView только через код?

                  IscanderChe
                  • 21 червня 2019 р. 03:17

                  Всё, с этим разобрался.

                    Коментарі

                    Only authorized users can post comments.
                    Please, Log in or Sign up
                    sf

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

                    • Результат:90бали,
                    • Рейтинг балів8
                    МВ

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

                    • Результат:68бали,
                    • Рейтинг балів-1
                    ЛС

                    C++ - Тест 001. Первая программа и типы данных

                    • Результат:53бали,
                    • Рейтинг балів-4
                    Останні коментарі
                    A
                    ALO1ZE19 жовтня 2024 р. 08:19
                    Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                    ИМ
                    Игорь Максимов05 жовтня 2024 р. 07:51
                    Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                    d
                    dblas505 липня 2024 р. 11:02
                    QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                    k
                    kmssr08 лютого 2024 р. 18:43
                    Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                    АК
                    Анатолий Кононенко05 лютого 2024 р. 01:50
                    Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                    Тепер обговоріть на форумі
                    J
                    JacobFib17 жовтня 2024 р. 03:27
                    добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
                    ИМ
                    Игорь Максимов03 жовтня 2024 р. 04:05
                    Реализация навигации по разделам Спасибо Евгений!
                    JW
                    Jhon Wick01 жовтня 2024 р. 15:52
                    Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
                    КГ
                    Кирилл Гусарев27 вересня 2024 р. 09:09
                    Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
                    F
                    Fynjy22 липня 2024 р. 04:15
                    при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

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