Search code examples
pythonqtmatplotlibpyqtpyside2

self.window.windowHandle() returns None in backend_qt with PySide2


I am working on a GUI window using PySide2 in Python 3.8.10 (Not my choice). When running the sample code an error is produced in the backend_qt package, which is being used to embed a matplotlib plot in the window. This isn't a big issue in this program, but when it's implemented with the rest of the project I believe it's causing the window to crash and/or not display properly

import sys
from matplotlib import pyplot as plt
from PySide2.QtWidgets import (QHBoxLayout, QWidget, QApplication)
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg

class MplCanvas(FigureCanvasQTAgg):
    # Create canavs to display graph
    def __init__(self, parent, width=15, height=4, dpi=100):
        fig, self.axis = plt.subplots(figsize=(width, height), dpi=dpi)
        super().__init__(fig)
        self.setParent(parent)
        self.window = FigureCanvasQTAgg

class OutputWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.chart = MplCanvas(self)
        self.create_params_box()

    def create_params_box(self):

        self.hbox = QHBoxLayout()
        self.hbox.addWidget(self.chart)

app = QApplication(sys.argv)
demo = OutputWindow()
demo.setLayout(demo.hbox)
demo.showMaximized()
sys.exit(app.exec_())

Output

Traceback (most recent call last):
  File "~\venv\lib\site-packages\matplotlib\backends\backend_qt.py", line 276, in showEvent
    window.screenChanged.connect(self._update_screen)
AttributeError: 'NoneType' object has no attribute 'screenChanged'

From backend_qt

    def showEvent(self, event):

        window = self.window().windowHandle()
        window.screenChanged.connect(self._update_screen)
        self._update_screen(window.screen())

Obviously this means self.window().windowHandle() is returning None but I'm not sure why this would be the case. This gets output 2 times, once when the window opens, and again when it's closed by the user

I'm not sure if this is an issue on my end or with PySide2 (it would not be the first) but I would appreciate a workaround.

Thanks!

Stripped original code down to demo Changing PySide2 version to 5.15.2, 5.15.1, 5.14.x Sample code produces ok output but window crashes when implemented into full system


Solution

  • You are incorrectly embedding the Matplotlib canvas. See the official documentation.

    Do like the following example, which is based on your example.

    from matplotlib import pyplot as plt
    from PySide2.QtWidgets import (QHBoxLayout, QWidget, QApplication)
    from matplotlib.backends.backend_qtagg import FigureCanvas
    
    class MplCanvas(FigureCanvas):
        def __init__(self, width=15, height=4, dpi=100):
            fig, self.axis = plt.subplots(figsize=(width, height), dpi=dpi)
            super().__init__(fig)
    
    class OutputWindow(QWidget):
        def __init__(self):
            super().__init__()
            self.chart = MplCanvas()
            hbox = QHBoxLayout()
            self.setLayout(hbox)
            hbox.addWidget(self.chart)
    
    app = QApplication()
    demo = OutputWindow()
    demo.show()
    app.exec_()