2

I'm using a QSqlTableModel as a data source and a QTableView to display the data. Also I'm using a QDataWidgetMapper to edit the data in a seperate form.

All I want to do is translate a Date/Time string from one format in the database (2011-07-09T18:21:49) to a different format to show in the table (18:21) and another format for the editor mapping (09.07.2011 18:21:49)

I think ItemDelegate is the right way, but I don't want to change the painting etc... How do I do it the right way?

Philipp F
  • 874
  • 9
  • 29

3 Answers3

2

Ok I think this might be the right way to do it (an intermediate data model), but now I used a QItemDelegate. I did the following and it worked:

class DateTimeDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit DateTimeDelegate(QObject *parent = 0);

void setEditorData(QWidget *editor,
                   const QModelIndex &index) const;

void setModelData(QWidget *editor,
                  QAbstractItemModel *model,
                  const QModelIndex &index) const;

void paint(QPainter *painter, const QStyleOptionViewItem &option,
           const QModelIndex &index) const;

signals:

public slots:

};

Implementation:

void DateTimeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    if(index.column() == 1 || index.column() == 2)  {
        if (editor->property("text").isValid()) {
            QDateTime dt = QDateTime::fromString(index.data().toString(), Qt::ISODate);
            editor->setProperty("text", dt.toString("dd.MM.yyyy hh:mm"));
        }
    } else {
        QItemDelegate::setEditorData(editor, index);
    }
}

void DateTimeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
           const QModelIndex &index) const
{
    QDateTime dt = QDateTime::fromString(index.data().toString(), Qt::ISODate);


    QString time;
    if(dt.date() == QDate::currentDate())
        time = dt.toString("hh:mm");
    else
        time = dt.toString("dd.MM.");

    painter->save();
    painter->setClipRect(option.rect);

    drawBackground(painter, option, index);
    drawDisplay(painter, option, option.rect, time);
    drawFocus(painter, option, option.rect);

    painter->restore();
}   
Philipp F
  • 874
  • 9
  • 29
  • Just as an update: the docs currently recommend using QStyleItemDelegate: https://stackoverflow.com/questions/28871121/what-is-the-difference-between-qitemdelegate-and-qstyleditemdelegate – adam.baker Apr 27 '19 at 14:43
0

This very task is the example used in the documentation for QIdentityProxyModel. That's the appropriate way to do it. From the docs:

class DateFormatProxyModel : public QIdentityProxyModel
{
  // ...

  void setDateFormatString(const QString &formatString)
  {
    m_formatString = formatString;
  }

  QVariant data(const QModelIndex &index, int role) const override
  {
    if (role != Qt::DisplayRole)
      return QIdentityProxyModel::data(index, role);

    const QDateTime dateTime = sourceModel()->data(SourceClass::DateRole).toDateTime();

    return dateTime.toString(m_formatString);
  }

private:
  QString m_formatString;
};
adam.baker
  • 1,447
  • 1
  • 14
  • 30
0

I think you have to use proxy data model, not a ItemDelegate

TheHorse
  • 2,787
  • 1
  • 23
  • 32