[PyQt] SystemLocaleShortDate omits the century on Linux

J Barchan jnbarchan at gmail.com
Sat Mar 14 09:57:58 GMT 2020

Hi Maurizio,

I have been keeping an eye on this thread.

> you only have to subclass it and override data(): if the source data is
actually a QDate, return the format that better suits your needs
> return data.toString(self.dateFormat())

This --- overriding data() --- is precisely what I did for dates, and also
for outputting floats as 2-decimal-point string format, which is what we
wanted.  It seemed natural to me, and it's what I did from C#/.NET for
similar situation.

*However*, I was screamed at over at the Qt forum.  The experts told me in
no uncertain terms that this was *not* the thing to do, to get a string
format for a type which you wanted.  They insisted I should be doing it via
QStyledItemDelegate, for whatever view I was in.  I should not handle the
data(Qt.DisplayRole) and return a string, I should leave that (like
Qt.EditRole) returning the underlying value type, not my desired format.
Indeed, they basically said the only time I should separate, say,
DisplayRole from EditRole, is the kind of case quoted I think in the docs,
where you have a spreadsheet with formulae and the thing you edit (the
formula) is effectively quite a different data item from the number you end
up displaying when evaluated.

So... I'd be interested to hear your/anyone's views?  Also, the example you
give above for date output format from data(), would you equally implement
that if, say, you knew you wanted your float values to come out with 2
decimal places (and possibly a leading/trailing currency symbol), or would
you say there is a difference there from dates?

Thanks for anyone's comments!

On Fri, 13 Mar 2020 at 21:27, Maurizio Berti <maurizio.berti at gmail.com>

> As far as I know, Unix "date +%x" returns the locale d_fmt, which is not
> necessarily the "shortest" form.
> I believe that Qt relies on its own "super-set" of localizations, but I'm
> just guessing.
> About your second question, you don't have to necessarily use a delegate,
> and subclassing is usually enough.
> If you're using a QStandardItemModel, you only have to subclass it and
> override data(): if the source data is actually a QDate, return the format
> that better suits your needs.
> Since you'll probably use a database as a source for the model, using
> QIdentityProxyModel is usually much better.
> In this example I'll fill a simple table with a date column, and a
> subclass of QIdentityProxyModel returns the data in the selected format
> whenever a DisplayRole returns a QDate.
> In this way you don't need a delegate, if not for the editor; I also added
> a "companion" delegate for the proxy, so that if it is going to show a
> QDateEdit and the model is the proxy, it will use the same format set for
> it.
> class DateProxyModel(QtCore.QIdentityProxyModel):
>     def dateFormat(self):
>         try:
>             return self._dateFormat
>         except:
>             return QtCore.QLocale().dateFormat(QtCore.QLocale.ShortFormat)
>     def setDateFormat(self, fmt=''):
>         if not fmt:
>             del self._dateFormat
>         else:
>             self._dateFormat = fmt
>         # the date format has changed, notify all connected views about
> that
>         self.dataChanged.emit(QtCore.QModelIndex(), QtCore.QModelIndex())
>     def data(self, index, role=QtCore.Qt.DisplayRole):
>         data = super().data(index, role)
>         if role == QtCore.Qt.DisplayRole and isinstance(data,
> QtCore.QDate):
>             return data.toString(self.dateFormat())
>         return data
> class DateProxyDelegate(QtWidgets.QStyledItemDelegate):
>     def createEditor(self, parent, option, index):
>         editor = super().createEditor(parent, option, index)
>         if isinstance(editor, QtWidgets.QDateEdit) and
> isinstance(index.model(), DateProxyModel):
>             editor.setDisplayFormat(index.model().dateFormat())
>         return editor
> class Test(QtWidgets.QWidget):
>     def __init__(self):
>         super().__init__()
>         layout = QtWidgets.QVBoxLayout(self)
>         formatEdit = QtWidgets.QLineEdit()
>         layout.addWidget(formatEdit)
>         table = QtWidgets.QTableView()
>         layout.addWidget(table)
>         model = QtGui.QStandardItemModel()
>         model.setHorizontalHeaderLabels(['Date', 'Something'])
>         for row in range(10):
>             dateItem = QtGui.QStandardItem()
>             d = QtCore.QDate(randrange(2000, 2021), randrange(1, 13),
> randrange(1, 29))
>             dateItem.setData(d, QtCore.Qt.DisplayRole)
>             model.appendRow([dateItem, QtGui.QStandardItem('something')])
>         proxy = DateProxyModel()
>         proxy.setSourceModel(model)
>         table.setModel(proxy)
>         dateDelegate = DateDelegate()
>         table.setItemDelegate(dateDelegate)
>         formatEdit.setPlaceholderText(proxy.dateFormat())
>         formatEdit.textChanged.connect(proxy.setDateFormat)
> Cheers,
> Maurizio
> Il giorno ven 13 mar 2020 alle ore 15:48 Sibylle Koczian <
> nulla.epistola at web.de> ha scritto:
>> Am 11.03.2020 um 20:47 schrieb Maurizio Berti:
>> > It completely depends on how the system "tells" what is the date format.
>> > Apparently, Windows defaults to 4 digits for your localization, while
>> > it's set to 2 for Linux.
>> So I thought too, but then why does "date +%x", which should show "the
>> locale's date representation", give all 4 digits? This is very confusing.
>> > You can change them in both systems: in Windows it's on the regional
>> > settings, while on Linux it depends on your distro/window manager/etc.
>> >
>> In this case Windows does it right. I'll have yet to find the right
>> setting for Linux. But in the meantime: if I want a QTableView to render
>> QDate values in another format, a custom delegate is the way to go,
>> right? But which method? All the examples I've seen for overwritten
>> paint() methods seem unnecessary complicated for this sort of small
>> change.
>> Sibylle
>> _______________________________________________
>> PyQt mailing list    PyQt at riverbankcomputing.com
>> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
> --
> È difficile avere una convinzione precisa quando si parla delle ragioni
> del cuore. - "Sostiene Pereira", Antonio Tabucchi
> http://www.jidesk.net
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20200314/c298bf48/attachment-0001.htm>

More information about the PyQt mailing list