Как сохранить значения Date как целые числа в SQLite, используя QSqlTableModel - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь сохранить значения Date из приложения Qt в базе данных SQLite как целые числа.

Я создал делегат даты с этими функциями:

QWidget* DateDelegate::createEditor(QWidget* parent,
    const QStyleOptionViewItem& option,
    const QModelIndex& index) const
{
  QDateTimeEdit* editor = new QDateTimeEdit(parent);
  editor->setDisplayFormat("dd.MM.yyyy");
  editor->setCalendarPopup(true);
  editor->setDateTime(QDateTime::fromSecsSinceEpoch(index.data().toLongLong()*86400));
  return (editor);
}

void DateDelegate::setEditorData(QWidget* paramEditor, const QModelIndex &index) const
{
  QDateTimeEdit* editor = static_cast<QDateTimeEdit*>(paramEditor);
  editor->setDateTime(QDateTime::fromSecsSinceEpoch(index.data().toLongLong()*86400));
}

void DateDelegate::setModelData(QWidget *paramEditor, QAbstractItemModel *model, const QModelIndex& index) const
{
  QDateTimeEdit *editor = static_cast<QDateTimeEdit *>(paramEditor);
  model->setData(index, editor->dateTime().toSecsSinceEpoch()/86400);
}

И модель DTMCode SubClassed только с данными () переопределена:

QVariant DTModel::data(const QModelIndex &index, int role) const
{
    if (role!=Qt::DisplayRole) {
        return QSqlTableModel::data(index,role);
    }
    if (index.column() != fieldIndex("datnaskld")) {
        return QSqlTableModel::data(index,role);
    }
    QVariant value = QDateTime::fromSecsSinceEpoch(QSqlQueryModel::data(index, role).toInt()*86400).toString("dd.MM.yyyy");
    return value;
}

Числа отображаются в основном какдаты.

Но у меня проблема: когда поле вводится в режиме редактирования, дата всегда изменяется на 01.01.1970 (означает 0 внутри)

Чего здесь не хватает? ..

Другая проблема заключается в том, что setItemDelegateForColumn () не работает должным образом.У меня есть эта команда в коде:

ui->tableViewP->setItemDelegateForColumn(m->fieldIndex("datnaskld"), new DateDelegate(ui->tableViewP));

Но делегат присваивается всем столбцам, а не только указанному столбцу.Поэтому я добавил эти странные команды в делегат:

if (index.column() != fieldIndex("datnaskld")) {
     return QSqlTableModel::data(index,role);
}

1 Ответ

0 голосов
/ 17 октября 2018

Ниже мое решение основано на том, что я узнал здесь .

Теперь мое понимание ролей намного лучше.

Я перенес все вычисления в модель, иDateDelegate - это «чистый» редактор.Модель возвращает QString для Qt :: DisplayRole и QDateTime для Qt :: EditRole.

Реализация делегата даты:

QWidget* DateDelegate::createEditor(QWidget* parent,
                                    const QStyleOptionViewItem& option,
                                    const QModelIndex& index) const
{
    QDateTimeEdit* editor = new QDateTimeEdit(parent);
    editor->setDisplayFormat("dd.MM.yyyy");
    editor->setCalendarPopup(true);
    return (editor);
}

void DateDelegate::setEditorData(QWidget* editor, const QModelIndex &index) const
{
    QDateTimeEdit* ed = static_cast<QDateTimeEdit*>(editor);
    ed->setDateTime(index.data(Qt::EditRole).toDateTime());
}

void DateDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const
{
    QDateTimeEdit *ed = static_cast<QDateTimeEdit *>(editor);
    model->setData(index, ed->dateTime(),Qt::EditRole);
}

Реализация DTModel:

QVariant DTModel::data(const QModelIndex &index, int role) const
{
    if (role!=Qt::DisplayRole && role!=Qt::EditRole) {
        return QSqlRelationalTableModel::data(index,role);
    }
    if (index.column() != fieldIndex("datnaskld")) {
        return QSqlRelationalTableModel::data(index,role);
    }

    QVariant value = QSqlRelationalTableModel::data(index, role);
    if (role==Qt::EditRole) {
        value = QDateTime::fromSecsSinceEpoch((value.toLongLong()-25569)*86400);
    } else {
        value = QDateTime::fromSecsSinceEpoch((value.toLongLong()-25569)*86400).toString("dd.MM.yyyy");
    }
    return value;
}

bool DTModel::setData(const QModelIndex &item, const QVariant &value, int role)
{
    if (item.column() != this->fieldIndex("datnaskld")) {
        return QSqlRelationalTableModel::setData(item,value,role);
    }
    QVariant v = value.toDateTime().toSecsSinceEpoch()/86400+25569;
    return QSqlRelationalTableModel::setData(item,v,role);
};

Я добавляю/ вычитая 25569 дней, чтобы получить те же числа, что MS Excel использует для даты.Кстати, я нашел ошибку в MS Excel - швы в том, что 1900 год считается високосным годом. Так что для числа 60 Qt показывает 1.3.1900, но в Excel 29.2.1900 и все более старые даты неверны в Excel.

...