Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/release_notes/release_3.17.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* **Application startup blocked by a corrupted translation file** — when a `.mo` translation catalog was corrupted or unreadable (e.g. truncated during installation), importing guidata failed with an error such as `OSError: Bad magic number`. The same applied to any application relying on `guidata.configtools.get_translation`, like PlotPy, Sigima or DataLab, so the application could not start at all. The interface now falls back to English, and a `RuntimeWarning` identifies the faulty catalog (fixes [Issue #119](https://github.com/PlotPyStack/guidata/issues/119)).
* **Error when editing a dictionary field in a JSON Schema based form** — in a form generated with `guidata.dataset.dataset_to_schema` (e.g. in a web frontend), editing a `DictItem` field failed with `TypeError: DictItem.__dictedit() missing 1 required positional argument: 'parent'`: the button opening the dictionary editor in the Qt interface was handled as a callback updating the other fields. `DictItem` fields are no longer flagged with `x-guidata-has-callback`, and `resolve_dataset_callbacks` returns an empty mapping for them (fixes [Issue #123](https://github.com/PlotPyStack/guidata/issues/123)).
* **Date/time callback never called** — the `display` callback of a `DateTimeItem` was never called when the date or time was changed in a dataset editor, so that the values computed from it were not updated. The callback is now called on each change, with the new value of the item (a `datetime.datetime` object), like for the other items (fixes [Issue #123](https://github.com/PlotPyStack/guidata/issues/123)).
* **Date callback received a Qt object** — the `display` callback of a `DateItem` received a Qt `QDateTime` object, whose type depends on the Qt binding (PyQt5, PyQt6 or PySide6), instead of the value of the item. It now receives the new value of the item (a `datetime.date` object), like the other items. Callbacks relying on the previous `QDateTime` argument must be updated (fixes [Issue #126](https://github.com/PlotPyStack/guidata/issues/126)).
* **Plain-text "about" information** — `guidata.widgets.about.about(html=False)` (and `AboutInfo.about(html=False)`) failed with `UnboundLocalError` instead of returning the information about the package as plain text (fixes [Issue #123](https://github.com/PlotPyStack/guidata/issues/123)).
* **French translations of the DataFrame editor** — when entering a number format not starting with `%`, the French error message stated the opposite of the actual rule ("must not start with '%'"), and the title of the export dialog box was shown in English. Both are now correctly translated (fixes [Issue #123](https://github.com/PlotPyStack/guidata/issues/123)).

Expand Down
7 changes: 4 additions & 3 deletions guidata/dataset/qtitemwidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -757,9 +757,10 @@ def __init__(
qt_fmt = convert_date_format(fmt)
self.dateedit.setDisplayFormat(qt_fmt)

def date_changed(self, value):
"""Date changed"""
_display_callback(self, value)
def date_changed(self, _value) -> None:
"""Date changed (the ``QDateTime`` argument is ignored: the callback
receives the Python value of the widget)"""
_display_callback(self, self.value())
self.notify_value_change()

def get(self) -> None:
Expand Down
39 changes: 35 additions & 4 deletions guidata/tests/unit/test_datetime_display_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
# (see guidata/LICENSE for details)

"""
Test the display callback of DateTimeItem
Test the display callbacks of DateItem and DateTimeItem

When the date/time is changed in a dataset editor, the ``display`` callback of a
``DateTimeItem`` must be called with the Python value of the item (``datetime``).
When the date (or date/time) is changed in a dataset editor, the ``display``
callback of a ``DateItem`` (or ``DateTimeItem``) must be called with the Python
value of the item (``date`` or ``datetime``), not with a Qt object.
"""

from __future__ import annotations
Expand All @@ -18,11 +19,41 @@
from qtpy import QtWidgets as QW

from guidata.dataset import DataSet
from guidata.dataset.dataitems import DateTimeItem
from guidata.dataset.dataitems import DateItem, DateTimeItem
from guidata.dataset.qtwidgets import DataSetEditLayout
from guidata.qthelpers import qt_app_context


def test_date_display_callback() -> None:
"""Changing the date calls the display callback with a date"""
calls = []

def callback(instance: DataSet, _item: DateItem, value) -> None:
"""Record the callback value and the dataset value"""
calls.append((value, instance.date))

class _DateDataSet(DataSet):
"""Dataset with a date item having a display callback"""

date = DateItem("Date", default=datetime.date(2010, 10, 10)).set_prop(
"display", callback=callback
)

with qt_app_context():
dialog = QW.QDialog()
dataset = _DateDataSet()
layout = DataSetEditLayout(dialog, dataset, QW.QGridLayout(dialog))
try:
(widget,) = layout.get_terminal_widgets()
calls.clear()
widget.dateedit.setDate(QC.QDate(2024, 1, 2))
expected = datetime.date(2024, 1, 2)
assert calls == [(expected, expected)]
assert type(calls[0][0]) is datetime.date
finally:
dialog.deleteLater()


def test_datetime_display_callback() -> None:
"""Changing the date/time calls the display callback with a datetime"""
calls = []
Expand Down
Loading