Валидация на ввод даты в QTableView

Я использую QTableView вместе с QSqlRelationalModel. У меня есть колонка с датой в формате строки и я хочу сделать валидацию или ввод через виджет-календарь. Как?


Ответы (1 шт):

Автор решения: Alexander Chernin

Например, для редактирования даты QDateEdit (для валидатора QValidator с QLineEdit, QDateTimeEdit, и любого другого виджета - тоже самое), это делается через наследование QStyledItemDelegate и переопределения функции createEditor:

class DateStyledDelegate: public QStyledItemDelegate {
    Q_OBJECT
public:
    // Метод создания виджетов для соответствующих ячеек таблицы
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
        if (index.isValid()) {
            if (index.column() == <Номер колонки с датой>) {
                // Создаем виджет редактирования даты в ячейке
                QDateEdit* dateEdit = new QDateEdit(parent);
                dateEdit->setGeometry(option.rect);
                // Чтобы редактировать дату через календарь
                // надо установить: 
                dateEdit.setCalendarPopup(true);
                return dateEdit;
            }
        }
        // Обязательно, для вызова редакторов по умолчанию
        return QStyledItemDelegate::createEditor(parent, option, index);
    }
    
    // Инициализируем наш виджет текущим значением
    void setEditorData(QWidget *editor, const QModelIndex &index) const {
        if (index.isValid() && index.column() == <ну, вы в курсе>) {
            QDateEdit* dateEdit = qobject_cast<QDateEdit*>(editor);
            if (dateEdit) {
                // Получаем текущее значение из ячейки
                QString value = index.data().toString();
                QDate date = QDate::fromString(value, <Формат даты>);
                dateEdit->setDate(/*const QDate &*/ date);
                return;
            }
        }
        QStyledItemDelegate::setEditorData(editor, index);
    }

}

Далее, надо установить наш делегат в объект таблицы:

// для всей таблицы
ui->tableView->setItemDelegate(new DateStyledDelegate());

//либо для колонки
ui->tableView->setItemDelegateForColumn(<соответствующая колонка>, new DateStyledDelegate());

//либо для строки
ui->tableView->setItemDelegateForRow(<соответствующая строка>, new DateStyledDelegate());
→ Ссылка