如何使用QSqlTableModel将日期值作为整数存储到SQLite中

时间:2018-10-17 11:52:56

标签: qt sqlite date datetime qsqltablemodel

我试图将Qt应用程序中的Date值存储为整数。

我创建了具有以下功能的日期委托:

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);
}

重新实现了只有data()的子类化模型DTModel:

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 :(得分:0)

以下是根据我学到的here得出的解决方案。

现在我对角色的了解要好得多。

我将所有计算移到了模型上,DateDelegate是“纯”编辑器。模型为Qt :: DisplayRole返回QString,为Qt :: EditRole返回QDateTime。

日期委托的实现:

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内部使用的Date相同的数字。顺便说一句,我发现了MS Excel中的错误-接缝那年1900年被认为是leap年。.因此对于数字60 Qt显示1.3.1900,但是在Excel 29.2.1900中,并且所有旧日期在excel中都是错误的。