Skip to content

Commit

Permalink
create the utils.save_image function
Browse files Browse the repository at this point in the history
  • Loading branch information
jborbely committed Jul 27, 2021
1 parent cda10b6 commit 33abbb4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 7 deletions.
10 changes: 5 additions & 5 deletions msl/qt/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
"""
import traceback as tb

from .utils import logger
from .utils import (
logger,
save_image,
)
from . import (
Qt,
QtGui,
QtWidgets,
application,
prompt,
Expand Down Expand Up @@ -91,9 +93,7 @@ def __init__(self):
def save_screenshot(self):
filename = prompt.save(filters='Images (*.png *.jpg *.jpeg *.bmp)')
if filename:
pixmap = QtGui.QPixmap(self.size())
self.render(pixmap)
pixmap.toImage().save(filename)
save_image(self, filename)

def show_hide_details(self):
if self.detailed_textedit.isVisible():
Expand Down
34 changes: 33 additions & 1 deletion msl/qt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
import fnmatch
import logging

from . import application
from . import (
QtGui,
application,
)

__all__ = (
'drag_drop_paths',
'save_image',
'screen_geometry',
)

Expand Down Expand Up @@ -41,6 +45,34 @@ def drag_drop_paths(event, *, pattern=None):
return []


def save_image(widget, path, *, quality=-1):
"""Save a widget to an image file.
Parameters
----------
widget : :class:`QtWidgets.QWidget`
The widget to save as an image.
path : :class:`str`
The file path to save the image to. The image format is chosen
based on the file extension.
quality : :class:`int`, optional
The quality factor. Must be in the range 0 to 100 or -1. Specify 0 to
obtain small compressed files, 100 for large uncompressed files, and
-1 (the default) to use the default settings.
Returns
-------
:class:`QtGui.QPixmap`
The `widget` as a pixmap object.
"""
pixmap = QtGui.QPixmap(widget.size())
widget.render(pixmap)
success = pixmap.toImage().save(path, quality=quality)
if not success:
raise OSError(f'Cannot save image to {path!r}')
return pixmap


def screen_geometry(widget=None):
"""Get the geometry of a desktop screen.
Expand Down
31 changes: 30 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
from msl.qt import utils, QtCore, QtWidgets, Qt, QtGui
import os.path
from tempfile import NamedTemporaryFile

import pytest

from msl.qt import (
Qt,
QtGui,
QtCore,
QtWidgets,
utils,
application,
)


def test_screen_geometry():
Expand Down Expand Up @@ -46,3 +58,20 @@ def test_drag_enter_paths():
paths = utils.drag_drop_paths(event, pattern='*.png')
assert len(paths) == 1
assert '/path/to/image.png' in paths


def test_save_image():
app = application()
file = NamedTemporaryFile()

# no file extension is specified so cannot determine the image format
with pytest.raises(OSError, match=r'Cannot save image'):
utils.save_image(QtWidgets.QWidget(), file.name)

path = file.name+'.png'
assert not os.path.isfile(path)
pixmap = utils.save_image(QtWidgets.QWidget(), path)
assert os.path.isfile(path)
assert isinstance(pixmap, QtGui.QPixmap)

file.close()

0 comments on commit 33abbb4

Please sign in to comment.