diff --git a/lib/matplotlib/backends/backend_qt.py b/lib/matplotlib/backends/backend_qt.py index 9089e982cea6..401ce0b0b754 100644 --- a/lib/matplotlib/backends/backend_qt.py +++ b/lib/matplotlib/backends/backend_qt.py @@ -262,12 +262,21 @@ def _update_screen(self, screen): screen.physicalDotsPerInchChanged.connect(self._update_pixel_ratio) screen.logicalDotsPerInchChanged.connect(self._update_pixel_ratio) + def eventFilter(self, source, event): + if event.type() == QtCore.QEvent.Type.DevicePixelRatioChange: + self._update_pixel_ratio() + return super().eventFilter(source, event) + def showEvent(self, event): # Set up correct pixel ratio, and connect to any signal changes for it, # once the window is shown (and thus has these attributes). window = self.window().windowHandle() - window.screenChanged.connect(self._update_screen) - self._update_screen(window.screen()) + current_version = tuple(int(x) for x in QtCore.qVersion().split('.', 2)[:2]) + if current_version >= (6, 6): + window.installEventFilter(self) + else: + window.screenChanged.connect(self._update_screen) + self._update_screen(window.screen()) def set_cursor(self, cursor): # docstring inherited diff --git a/lib/matplotlib/tests/test_backend_qt.py b/lib/matplotlib/tests/test_backend_qt.py index 60f8a4f49bb8..a85bc269e5b8 100644 --- a/lib/matplotlib/tests/test_backend_qt.py +++ b/lib/matplotlib/tests/test_backend_qt.py @@ -137,7 +137,7 @@ def on_key_press(event): @pytest.mark.backend('QtAgg', skip_on_importerror=True) -def test_device_pixel_ratio_change(): +def test_device_pixel_ratio_change(qt_core): """ Make sure that if the pixel ratio changes, the figure dpi changes but the widget remains the same logical size. @@ -154,11 +154,19 @@ def test_device_pixel_ratio_change(): def set_device_pixel_ratio(ratio): p.return_value = ratio - # The value here doesn't matter, as we can't mock the C++ QScreen - # object, but can override the functional wrapper around it. - # Emitting this event is simply to trigger the DPI change handler - # in Matplotlib in the same manner that it would occur normally. - screen.logicalDotsPerInchChanged.emit(96) + window = qt_canvas.window().windowHandle() + current_version = tuple( + int(x) for x in qt_core.qVersion().split('.', 2)[:2]) + if current_version >= (6, 6): + qt_core.QCoreApplication.sendEvent( + window, + qt_core.QEvent(qt_core.QEvent.Type.DevicePixelRatioChange)) + else: + # The value here doesn't matter, as we can't mock the C++ QScreen + # object, but can override the functional wrapper around it. + # Emitting this event is simply to trigger the DPI change handler + # in Matplotlib in the same manner that it would occur normally. + window.screen().logicalDotsPerInchChanged.emit(96) qt_canvas.draw() qt_canvas.flush_events() @@ -168,7 +176,6 @@ def set_device_pixel_ratio(ratio): qt_canvas.manager.show() size = qt_canvas.size() - screen = qt_canvas.window().windowHandle().screen() set_device_pixel_ratio(3) # The DPI and the renderer width/height change