[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>
wrote:
> 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
>
--
Kindest,
Jonathan
<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
Virus-free.
www.avast.com
<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
<#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
-------------- 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