PDA

View Full Version : QTableView Date display format difference linux vs. Windows



schnitzel
18th March 2011, 04:11
I wrote an application that displays a table from a mysql db using QTableView. One of the columns is a Date.

On Windows it displays as yyyy-mm-dd but on linux is shows as yy-mm-dd.

Same code, same database.

The database lives on the Windows machine.

I have verified that the date format of the database is correct by using MySQL Query Browser running on the Linux machine.

Did I overlook something?

Rhayader
18th March 2011, 11:04
what you get by running the next code?


#include <QtCore/QCoreApplication>
#include <QLocale>
#include <QDebug>

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QLocale l=QLocale::system();
qDebug()<<l.dateFormat(QLocale::ShortFormat);
return a.exec();
}

schnitzel
18th March 2011, 18:56
on windows: yyyy-mm-dd
on linux: M/d/yy

I know how to change the short date format on Windows... if I could only figure out how to do this on linux system wide.

Added after 1 48 minutes:


Tried both methods described on the following page:

http://ccollins.wordpress.com/2009/01/06/how-to-change-date-formats-on-ubuntu/

still the output from the above sample code still shows: "M/d/yy"

very frustrating...

schnitzel
18th March 2011, 20:04
Ok, just to recap.

I'm on Ubuntu 10.10 vanilla Qt 4.7.0.
default locale was en_US with short date M/d/yy which sucks.
I then changed locale to en_CA and got yy-MM-dd which is better but I'd like 4 digits for year.
I then changed locale en_CA d_fmt to %Y-%m-%d (and recompiled the locale), yet Qt sample code still gives:
yy-MM-dd
I even tried to change d_fmt to %F (confirmed with date +%F) result still:
yy-MM-dd

I'm extremely :confused:

Rhayader
18th March 2011, 20:39
This is a delegate I use for an application of my own. It is mostly copy-paste from the Qt examples and works fine for me.
the datedelegate.h:


#ifndef DATEDELEGATE_H
#define DATEDELEGATE_H

#include <QStyledItemDelegate>
class QStyleOptionViewItem;

class DateDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
DateDelegate(QObject *parent = 0,const int &dateColumn=0);

QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const;

void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const;
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;

signals:

public slots:
private:
int dtC;

};

#endif // DATEDELEGATE_H


and the datedelegate.cpp


#include "datedelegate.h"
#include <QStyleOptionViewItem>
#include <QModelIndex>
#include <QDateEdit>
#include <QPainter>
#include <QApplication>
#include <QTableView>
#include <QDebug>

DateDelegate::DateDelegate(QObject *parent, const int &dateColumn) :
QStyledItemDelegate(parent),dtC (dateColumn)
{
}

QWidget *DateDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if(index.isValid() && index.column() == dtC)
{
QWidget *editor = new QDateEdit(QDate::currentDate(), parent);
return editor;
}
else
return QStyledItemDelegate::createEditor(parent, option, index);
}

void DateDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
if(index.isValid() && index.column() == dtC)
{
QDate value = index.model()->data(index, Qt::EditRole).toDate();

QDateEdit *dateEdit = static_cast<QDateEdit*>(editor);
dateEdit->setCalendarPopup(true);
dateEdit->setDate(value);
}
else
QStyledItemDelegate::setEditorData(editor,index);
}

void DateDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
if(index.isValid() && index.column() == dtC)
{
QDateEdit *dateEdit = static_cast<QDateEdit*>(editor);
QDate value = dateEdit->date();

model->setData(index, value.toString("yyyy-MM-dd"), Qt::EditRole);
}

else
{
QStyledItemDelegate::setModelData(editor,model,ind ex);
}
}

void DateDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if(index.isValid() && index.column() == dtC)
editor->setGeometry(option.rect);
else
QStyledItemDelegate::updateEditorGeometry(editor, option, index);

}

void DateDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
painter->save();
if(index.isValid() && index.column() == dtC)
{
QDate value = index.model()->data(index, Qt::EditRole).toDate();
if (option.state & QStyle::State_Active)
{
QApplication::style()->drawItemText(painter, option.rect, Qt::AlignHCenter|Qt::AlignVCenter,
option.palette, true, value.toString("dd/MM/yyyy"),
(option.state&QStyle::State_Selected)?QPalette::HighlightedText: QPalette::WindowText);
}
else
{
QApplication::style()->drawItemText(painter, option.rect, Qt::AlignHCenter|Qt::AlignVCenter,
option.palette, true, value.toString("dd/MM/yyyy"),
QPalette::WindowText);
}
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
painter->restore();
}



The writing to model is done in line 51 in ISO format for a SQLite database.
Change lines 80 and 86 to whatever format you like for the tableView.

And for the sake of completeness:


#include "datedelegate.h"
......
DateDelegate dateDelegate=new DateDelegate(this,column);
ui->tableView->setItemDelegate(dateDelegate);
......


It is possible to rewrite the delegate without the column variable and use the setItemDelegateForColumn method of the tableView.

Added after 14 minutes:

Having just read the QLocale source code I think the LC_TIME is never read and I would not mess with the LANG or LC_ALL in my working machine. So just for the fun of it I wrote this trying to override what Qt reads from system


#include <QtCore/QCoreApplication>
#include <QLocale>
#include <QDebug>
#include <QVariant>
#include <QDate>

class MyLocal : QSystemLocale
{
#include <QSystemLocale>
public:
MyLocal() { };

QVariant query(QueryType type, QVariant in) const
{
if (type==QSystemLocale::DateToStringShort)
{
QDate inDate=in.toDate();
return inDate.toString("yy-M-d");
}
else if (type==QSystemLocale::DateToStringLong)
{
QDate inDate=in.toDate();
return inDate.toString("yyyy-MM-dd");
}
return QSystemLocale::query(type, in);
}
};

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyLocal m;
qDebug()<<QDate::currentDate().toString(Qt::DefaultLocaleSho rtDate);
qDebug()<<QDate::currentDate().toString(Qt::DefaultLocaleLon gDate);
return a.exec();
}


which is pretty stupid because the same could be done pretty simple as
QDate::currentDate().toString("yy-MM-dd")

schnitzel
18th March 2011, 20:59
Hi Rhayader,
thanks for investigating. I'll play around with this tonight.

schnitzel
19th March 2011, 03:39
overriding QSystemLocale worked like a charm.