Skip to content

Fix qt5 mouse #8440

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2157,7 +2157,7 @@ def print_figure(self, filename, dpi=None, facecolor=None, edgecolor=None,
dpi = rcParams['savefig.dpi']

if dpi == 'figure':
dpi = self.figure.dpi
dpi = getattr(self.figure, '_original_dpi', self.figure.dpi)

if facecolor is None:
facecolor = rcParams['savefig.facecolor']
Expand Down
32 changes: 21 additions & 11 deletions lib/matplotlib/backends/backend_qt5.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,11 @@ def _create_qApp():
qApp = app

if is_pyqt5():
qApp.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
try:
qApp.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
qApp.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
except AttributeError:
pass


class Show(ShowBase):
Expand All @@ -159,6 +163,7 @@ def mainloop(self):
global qApp
qApp.exec_()


show = Show()


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

def mouseEventCoords(self, pos):
"""
Calculate mouse coordinates in logical pixels.
"""Calculate mouse coordinates in physical pixels

Qt5 use logical pixels, but the figure is scaled to physical
pixels for rendering. Transform to physical pixels so that
all of the down-stream transforms work as expected.

Also, the origin is different and needs to be corrected.

Qt5 and Matplotlib use logical pixels, but the figure is scaled to
physical pixels for rendering. Also, the origin is different and needs
to be corrected.
"""
dpi_ratio = self._dpi_ratio
x = pos.x()
# flip y so y=0 is bottom of canvas
y = self.figure.bbox.height / self._dpi_ratio - pos.y()
return x, y
y = self.figure.bbox.height / dpi_ratio - pos.y()
return x * dpi_ratio, y * dpi_ratio

def mousePressEvent(self, event):
x, y = self.mouseEventCoords(event.pos())
Expand Down Expand Up @@ -579,7 +587,9 @@ def __init__(self, canvas, parent, coordinates=True):
def _icon(self, name):
if is_pyqt5():
name = name.replace('.png', '_large.png')
return QtGui.QIcon(os.path.join(self.basedir, name))
pm = QtGui.QPixmap(os.path.join(self.basedir, name))
pm.setDevicePixelRatio(self.canvas._dpi_ratio)
return QtGui.QIcon(pm)

def _init_toolbar(self):
self.basedir = os.path.join(matplotlib.rcParams['datapath'], 'images')
Expand All @@ -589,7 +599,7 @@ def _init_toolbar(self):
self.addSeparator()
else:
a = self.addAction(self._icon(image_file + '.png'),
text, getattr(self, callback))
text, getattr(self, callback))
self._actions[callback] = a
if callback in ['zoom', 'pan']:
a.setCheckable(True)
Expand All @@ -611,7 +621,7 @@ def _init_toolbar(self):
QtCore.Qt.AlignRight | QtCore.Qt.AlignTop)
self.locLabel.setSizePolicy(
QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Ignored))
QtWidgets.QSizePolicy.Ignored))
labelAction = self.addWidget(self.locLabel)
labelAction.setVisible(True)

Expand Down
22 changes: 13 additions & 9 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,10 @@ def __init__(self,
if frameon is None:
frameon = rcParams['figure.frameon']

self.dpi_scale_trans = Affine2D()
self.dpi = dpi
self.bbox_inches = Bbox.from_bounds(0, 0, *figsize)
self.dpi_scale_trans = Affine2D().scale(dpi, dpi)
# do not use property as it will trigger
self._dpi = dpi
self.bbox = TransformedBbox(self.bbox_inches, self.dpi_scale_trans)

self.frameon = frameon
Expand Down Expand Up @@ -413,6 +414,7 @@ def _get_dpi(self):
def _set_dpi(self, dpi):
self._dpi = dpi
self.dpi_scale_trans.clear().scale(dpi, dpi)
self.set_size_inches(*self.get_size_inches())
self.callbacks.process('dpi_changed', self)
dpi = property(_get_dpi, _set_dpi)

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

if forward:
ratio = getattr(self.canvas, '_dpi_ratio', 1)
dpival = self.dpi / ratio
canvasw = w * dpival
canvash = h * dpival
manager = getattr(self.canvas, 'manager', None)
if manager is not None:
manager.resize(int(canvasw), int(canvash))
canvas = getattr(self, 'canvas')
if canvas is not None:
ratio = getattr(self.canvas, '_dpi_ratio', 1)
dpival = self.dpi / ratio
canvasw = w * dpival
canvash = h * dpival
manager = getattr(self.canvas, 'manager', None)
if manager is not None:
manager.resize(int(canvasw), int(canvash))
self.stale = True

def get_size_inches(self):
Expand Down
12 changes: 12 additions & 0 deletions lib/matplotlib/tests/test_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,18 @@ def test_figaspect():
assert h / w == 1


@cleanup(style='default')
def test_change_dpi():
fig = plt.figure(figsize=(4, 4))
fig.canvas.draw()
assert fig.canvas.renderer.height == 400
assert fig.canvas.renderer.width == 400
fig.dpi = 50
fig.canvas.draw()
assert fig.canvas.renderer.height == 200
assert fig.canvas.renderer.width == 200


if __name__ == "__main__":
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)