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
                    AD

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

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

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

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

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

                    • Результат:20бали,
                    • Рейтинг балів-10
                    Останні коментарі
                    ИМ
                    Игорь Максимов22 листопада 2024 р. 11:51
                    Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                    Evgenii Legotckoi
                    Evgenii Legotckoi31 жовтня 2024 р. 14:37
                    Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                    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 аналогично. Могу предположить, что из-за более новой верси…
                    Тепер обговоріть на форумі
                    Evgenii Legotckoi
                    Evgenii Legotckoi24 червня 2024 р. 15:11
                    добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                    t
                    tonypeachey115 листопада 2024 р. 06:04
                    google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                    NSProject
                    NSProject04 червня 2022 р. 03:49
                    Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                    9
                    9Anonim25 жовтня 2024 р. 09:10
                    Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

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