QDateEdit委托的问题

时间:2014-05-06 13:49:12

标签: qt

我需要能够在QTableView中编辑日期,所以我实现了QItemDelegate:

#include "dateeditdelegate.h"

DateEditDelegate::DateEditDelegate(QObject *parent) :
    QItemDelegate(parent)
{
}

QWidget *DateEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QDateEdit * editor = new QDateEdit(parent);
    return editor;
}

void DateEditDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QDateEdit * dateEdit = static_cast<QDateEdit*>(editor);
    dateEdit->setDate(index.model()->data(index).toDate());
}

void DateEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QDateEdit * dateEdit = static_cast<QDateEdit*>(editor);
    model->setData(index, dateEdit->dateTime().toTime_t());
}

void DateEditDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);
}

我还重新实现了QSqlRelationalTableModel:

QVariant TblModel::data(const QModelIndex &item, int role) const
{
    if(item.column() == this->fieldIndex("add_date")){
        return QVariant(QDateTime::fromTime_t(QSqlQueryModel::data(item, role).toUInt()).date());
    }
    return QSqlQueryModel::data(item, role);
}

但结果我得到this

这些字段是可编辑的,但在编辑后不会保存新值(我可以将任何字段更改为&#34; 01.01.2015&#34;,但按Enter后它将恢复为&#34; 03.04.14&#34 )。此外,我无法理解,为什么会出现这些复选框。

1 个答案:

答案 0 :(得分:1)

您的主要问题是您不了解Qt提供的整个MVC框架。

您不需要自定义委托。默认值QItemDelegate已经知道如何为日期/时间数据创建编辑器。

问题第一部分的解决方案在于重新实现模型的data()

QSqlQueryModel被明确定义为只读模型。如果您希望编辑数据,则需要创建自己的机制来存储和编辑基础数据,您将通过重新实现setData()函数来更改这些数据。

如果要获得所需的结果,您需要迎合不同的角色。出于您的目的,您需要实施Qt::DisplayRoleQt::EditRoleQt::TextAlignmentRole

Qt::DisplayRole是在视图中显示的内容,最常用的格式为QString

Qt::EditRole是赋予委托的数据,以便它可以创建适当的编辑器窗口小部件并为其提供正确的数据。

Qt::TextAlignmentRole用于告诉视图如何将通过调用返回的数据与Qt::DisplayRole对齐。

QVariant TblModel::data(const QModelIndex &item, int role) const{

    if(item.column() == this->fieldIndex("add_date")){
        if (role == Qt::TextAlignmentRole){
            return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
        }

        QDateTime dateTime = QDateTime::fromTime_t(QSqlQueryModel::data(item, role).toUInt());
        if (role == Qt::DisplayRole){
            return dateTime.toString("dd.MM.yyyy");
        }
        if (role == Qt::EditRole){
            return dateTime.date();
        }
    }
    return QSqlQueryModel::data(item, role);
}

如果您希望数据可编辑,则需要使用与QSqlQueryModel不同的基本模型。您尚未实现的下一部分是更改模型中的数据。您可以通过重新实现setData()函数来完成此操作。

bool TblModel::setData(QModelIndex const &index, QVariant const &value, int role){
    if (!index.isValid() || role == Qt::EditRole){
        return false;
    }

    if (index.column() == fieldIndex("add_date")){
        // modify the underlying data

        if (validEdit){
            emit dataChanged(index, index); // signal to the view that the item needs to be redrawn
            return true;
        }
    }

    return false;
}