Skip to content

FormWidget fails to get a date or datetime value with PySide2 #18958

Closed

Description

@soininen

Bug report

Bug summary

matplotlib.backends.qt_editor._formlayout.FormWidget.get() converts values of date and datetime fields into python datetime.date and datetime.datetime objects using toPyDate() and toPyDateTime() methods. These exist only in PyQt5; in PySide2 the corresponding functions are called toPython().

One way to fix this is to patch matplotlib.backends.qt_compat._setup_pyqt5() by adding the following lines under if QT_API == QT_API_PYSIDE2:

    ...
    elif QT_API == QT_API_PYSIDE2:
        from PySide2 import QtCore, QtGui, QtWidgets, __version__
        import shiboken2
        def _isdeleted(obj): return not shiboken2.isValid(obj)
        QtWidgets.QDateTime.toPyDateTime = QtWidgets.QDateTime.toPython  # fix QDatetime
        QtWidgets.QDate.toPyDate = QtWidgets.QDate.toPython # fix QDate
    else:
    ....

Code for reproduction

from datetime import datetime
from PySide2.QtWidgets import QApplication
from matplotlib.backends.qt_editor._formlayout import FormWidget

QApplication()
widget = FormWidget([("Date time", datetime(year=2020, month=11, day=16))])
widget.setup()
values = widget.get()

Actual outcome

Traceback (most recent call last):
  File "formwidget.py", line 8, in <module>
    values = widget.get()
  File "lib\site-packages\matplotlib\backends\qt_editor\_formlayout.py", line 346, in get
    value = field.dateTime().toPyDateTime()
AttributeError: 'PySide2.QtCore.QDateTime' object has no attribute 'toPyDateTime'

Expected outcome

No output, especially no tracebacks.

Matplotlib version

  • Operating system: Windows 10
  • Matplotlib version: 3.3.0 (the bug seems to be in master too)
  • Matplotlib backend (print(matplotlib.get_backend())): qt5agg
  • Python version: 3.7.6
  • Jupyter version (if applicable):
  • Other libraries: PySide2

Activity

  1. anntzer commented on Nov 16, 2020

    @anntzer
    Contributor

    Thanks for the report; I don't think we should be patching the PySide2 API (it is what it is); an alternate solution would be along the lines of

    value = datetime.datetime.fromtimestamp(field.dateTime().toMSecsSinceEpoch() / 1000)

    However note that _formlayout is explicitly private and not suitable for general consumption; we reserve the right to change the module without notice (for example, given that we don't actually use this feature internally, we could certainly decide to "fix" this by just deleting the whole feature). Consider using the PyPI package (https://pypi.org/project/formlayout/) instead.

    OTOH this may be a good opportunity to fix the qt editor's behavior wrt units (currently it doesn't handle them at all...).

  2. soininen commented on Nov 16, 2020

    @soininen
    ContributorAuthor

    Thanks for the prompt answer. The issue actually boils down to the figure options editor: we are using date time values on the x axis extensively but the editor's axis limits shows date times as floats making adjustments difficult. I am monkey patching matplotlib.backends.qt_editor.figureoptions.figure_edit to convert the units to correct input widgets which made me discover the issue at hand. Fixing the editor to handle units correctly would indeed be more 'correct' approach.

  3. soininen commented on Dec 7, 2020

    @soininen
    ContributorAuthor

    As discussed above, the real fix for my problem would be to make Qt backend's figure options dialog to handle units properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions