Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7d9036c

Browse files
authored
Merge pull request #8440 from tacaswell/fix_qt5_mouse
Fix qt5 mouse
2 parents 2fb0da8 + 278e8ef commit 7d9036c

File tree

4 files changed

+47
-21
lines changed

4 files changed

+47
-21
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2157,7 +2157,7 @@ def print_figure(self, filename, dpi=None, facecolor=None, edgecolor=None,
21572157
dpi = rcParams['savefig.dpi']
21582158

21592159
if dpi == 'figure':
2160-
dpi = self.figure.dpi
2160+
dpi = getattr(self.figure, '_original_dpi', self.figure.dpi)
21612161

21622162
if facecolor is None:
21632163
facecolor = rcParams['savefig.facecolor']

lib/matplotlib/backends/backend_qt5.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,11 @@ def _create_qApp():
149149
qApp = app
150150

151151
if is_pyqt5():
152-
qApp.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
152+
try:
153+
qApp.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
154+
qApp.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
155+
except AttributeError:
156+
pass
153157

154158

155159
class Show(ShowBase):
@@ -159,6 +163,7 @@ def mainloop(self):
159163
global qApp
160164
qApp.exec_()
161165

166+
162167
show = Show()
163168

164169

@@ -261,17 +266,20 @@ def leaveEvent(self, event):
261266
FigureCanvasBase.leave_notify_event(self, guiEvent=event)
262267

263268
def mouseEventCoords(self, pos):
264-
"""
265-
Calculate mouse coordinates in logical pixels.
269+
"""Calculate mouse coordinates in physical pixels
270+
271+
Qt5 use logical pixels, but the figure is scaled to physical
272+
pixels for rendering. Transform to physical pixels so that
273+
all of the down-stream transforms work as expected.
274+
275+
Also, the origin is different and needs to be corrected.
266276
267-
Qt5 and Matplotlib use logical pixels, but the figure is scaled to
268-
physical pixels for rendering. Also, the origin is different and needs
269-
to be corrected.
270277
"""
278+
dpi_ratio = self._dpi_ratio
271279
x = pos.x()
272280
# flip y so y=0 is bottom of canvas
273-
y = self.figure.bbox.height / self._dpi_ratio - pos.y()
274-
return x, y
281+
y = self.figure.bbox.height / dpi_ratio - pos.y()
282+
return x * dpi_ratio, y * dpi_ratio
275283

276284
def mousePressEvent(self, event):
277285
x, y = self.mouseEventCoords(event.pos())
@@ -579,7 +587,9 @@ def __init__(self, canvas, parent, coordinates=True):
579587
def _icon(self, name):
580588
if is_pyqt5():
581589
name = name.replace('.png', '_large.png')
582-
return QtGui.QIcon(os.path.join(self.basedir, name))
590+
pm = QtGui.QPixmap(os.path.join(self.basedir, name))
591+
pm.setDevicePixelRatio(self.canvas._dpi_ratio)
592+
return QtGui.QIcon(pm)
583593

584594
def _init_toolbar(self):
585595
self.basedir = os.path.join(matplotlib.rcParams['datapath'], 'images')
@@ -589,7 +599,7 @@ def _init_toolbar(self):
589599
self.addSeparator()
590600
else:
591601
a = self.addAction(self._icon(image_file + '.png'),
592-
text, getattr(self, callback))
602+
text, getattr(self, callback))
593603
self._actions[callback] = a
594604
if callback in ['zoom', 'pan']:
595605
a.setCheckable(True)
@@ -611,7 +621,7 @@ def _init_toolbar(self):
611621
QtCore.Qt.AlignRight | QtCore.Qt.AlignTop)
612622
self.locLabel.setSizePolicy(
613623
QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
614-
QtWidgets.QSizePolicy.Ignored))
624+
QtWidgets.QSizePolicy.Ignored))
615625
labelAction = self.addWidget(self.locLabel)
616626
labelAction.setVisible(True)
617627

lib/matplotlib/figure.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,10 @@ def __init__(self,
323323
if frameon is None:
324324
frameon = rcParams['figure.frameon']
325325

326-
self.dpi_scale_trans = Affine2D()
327-
self.dpi = dpi
328326
self.bbox_inches = Bbox.from_bounds(0, 0, *figsize)
327+
self.dpi_scale_trans = Affine2D().scale(dpi, dpi)
328+
# do not use property as it will trigger
329+
self._dpi = dpi
329330
self.bbox = TransformedBbox(self.bbox_inches, self.dpi_scale_trans)
330331

331332
self.frameon = frameon
@@ -413,6 +414,7 @@ def _get_dpi(self):
413414
def _set_dpi(self, dpi):
414415
self._dpi = dpi
415416
self.dpi_scale_trans.clear().scale(dpi, dpi)
417+
self.set_size_inches(*self.get_size_inches())
416418
self.callbacks.process('dpi_changed', self)
417419
dpi = property(_get_dpi, _set_dpi)
418420

@@ -710,13 +712,15 @@ def set_size_inches(self, w, h=None, forward=True):
710712
self.bbox_inches.p1 = w, h
711713

712714
if forward:
713-
ratio = getattr(self.canvas, '_dpi_ratio', 1)
714-
dpival = self.dpi / ratio
715-
canvasw = w * dpival
716-
canvash = h * dpival
717-
manager = getattr(self.canvas, 'manager', None)
718-
if manager is not None:
719-
manager.resize(int(canvasw), int(canvash))
715+
canvas = getattr(self, 'canvas')
716+
if canvas is not None:
717+
ratio = getattr(self.canvas, '_dpi_ratio', 1)
718+
dpival = self.dpi / ratio
719+
canvasw = w * dpival
720+
canvash = h * dpival
721+
manager = getattr(self.canvas, 'manager', None)
722+
if manager is not None:
723+
manager.resize(int(canvasw), int(canvash))
720724
self.stale = True
721725

722726
def get_size_inches(self):

lib/matplotlib/tests/test_figure.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,18 @@ def test_figaspect():
214214
assert h / w == 1
215215

216216

217+
@cleanup(style='default')
218+
def test_change_dpi():
219+
fig = plt.figure(figsize=(4, 4))
220+
fig.canvas.draw()
221+
assert fig.canvas.renderer.height == 400
222+
assert fig.canvas.renderer.width == 400
223+
fig.dpi = 50
224+
fig.canvas.draw()
225+
assert fig.canvas.renderer.height == 200
226+
assert fig.canvas.renderer.width == 200
227+
228+
217229
if __name__ == "__main__":
218230
import nose
219231
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

0 commit comments

Comments
 (0)