Skip to content

[Bug]: AttributeError: 'QResizeEvent' object has no attribute 'pos'  #22409

Closed
@Valdes-Tresanco-MS

Description

@Valdes-Tresanco-MS

Bug summary

This bug is similar to #11607. In my case, I get it when I combine PyQt5 and matplotlib 3.5.1. In any of the other combinations (PyQt5 and matplotlib==3.4.3 or PyQt6 and matplotlib==3.5.1) it works as expected.

Code for reproduction

# change this to use PyQt5 or PyQt6
qt = 'qt5'

import sys
import matplotlib
from matplotlib.figure import Figure
if qt == 'qt6':
    from PyQt6.QtWidgets import *
    from PyQt6.QtCore import *
    from PyQt6.QtGui import *
    if matplotlib.__version__ == '3.4.3':
        raise ValueError('For PyQt6 Install matplotlib 3.5.1')
    from matplotlib.backends.backend_qtagg import (FigureCanvas, NavigationToolbar2QT as NavigationToolbar)


else:
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg as FigureCanvas,
                                                    NavigationToolbar2QT as NavigationToolbar)
import numpy as np

print('Matplotlib version:', matplotlib.__version__)


class ChartsBase(QMdiSubWindow):
    def __init__(self):
        super(ChartsBase, self).__init__()
        self.setMinimumSize(400, 400)

        self.mainwidgetmdi = QMainWindow()  # must be QMainWindow to handle the toolbar
        self.setWidget(self.mainwidgetmdi)

        fig = Figure()
        self.figure_canvas = FigureCanvas(fig)
        self.fig = self.figure_canvas.figure
        self.mainwidgetmdi.setCentralWidget(self.figure_canvas)
        # similar to figure canvas
        self.mpl_toolbar = NavigationToolbar(self.figure_canvas, self)
        self.mpl_toolbar.setVisible(True)
        if qt == 'qt6':
            area = Qt.ToolBarArea.BottomToolBarArea
        else:
            area = Qt.BottomToolBarArea
        self.mainwidgetmdi.addToolBar(area, self.mpl_toolbar)

        t = np.linspace(0, 10, 501)

        self.axes = self.fig.subplots(1, 1)
        line_plot_ax = self.axes.plot(t)


class MDIWindow(QMainWindow):
    count = 0

    def __init__(self):
        super().__init__()

        self.mdi = QMdiArea()
        self.setCentralWidget(self.mdi)
        bar = self.menuBar()

        file = bar.addMenu("File")
        file.addAction("New")
        file.triggered[QAction].connect(self.add_new)
        self.setWindowTitle("MDI Application with matplotlib")

    def add_new(self, p):

        if p.text() == "New":
            sub = ChartsBase()
            sub.setWindowTitle("Matplotlib example")
            self.mdi.addSubWindow(sub)
            sub.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mdi = MDIWindow()
    mdi.show()
    sys.exit(app.exec())

Actual outcome

To reproduce:

  1. execute the app
  2. Menu "File"
  3. "New"
  4. Maximize the subwindow

When the subwindow is maximized I get this error:

Traceback (most recent call last):
  File "/home/mario/programs/miniconda/lib/python3.8/site-packages/matplotlib/backends/backend_qt.py", line 262, in enterEvent
    x, y = self.mouseEventCoords(self._get_position(event))
AttributeError: 'QResizeEvent' object has no attribute 'pos'

Expected outcome

The maximized subwindow

Additional information

What are the conditions under which this bug happens? input parameters, edge cases, etc?

Using matplotlib==3.5.1 with PyQt5. Not happen with other combinations matplotlib==3.5.1 and PyQt6 or matplotlib==3.4.3 and PyQt5

Do you know why this bug is happening?

This bug is related to the QEvents methods. QResizeEvent does have not any method to get the position in PyQt5, unlike PyQt6 which does have it

Do you maybe even know a fix?

Add a try-except clausule to this method

def enterEvent(self, event):
x, y = self.mouseEventCoords(self._get_position(event))
FigureCanvasBase.enter_notify_event(self, guiEvent=event, xy=(x, y))

def enterEvent(self, event):
    try:
        x, y = self.mouseEventCoords(self._get_position(event))
    except AttributeError:
        # QResizeEvent has no attribute pos
        x = y = None
    FigureCanvasBase.enter_notify_event(self, guiEvent=event, xy=(x, y))

After this, work as expected!
Happy to open a PR if it is needed!

Operating system

Linux Mint 20.2

Matplotlib Version

3.5.1

Matplotlib Backend

QtAgg

Python version

Python 3.8.5

Jupyter version

No response

Installation

pip

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions