Commit 3840a32b authored by payno's avatar payno

[doc] update the snapshot qt directive

parent 5787dc81
......@@ -14,15 +14,13 @@ import logging
import os
import subprocess
import sys
from importlib.machinery import SourceFileLoader
from docutils.parsers.rst.directives.images import Figure
from silx.gui import qt
logging.basicConfig()
_logger = logging.getLogger(__name__)
# TODO:
# - Check if it is needed to patch block_text?
# RST directive ###############################################################
class SnapshotQtDirective(Figure):
......@@ -103,102 +101,61 @@ def setup(app):
return {'version': '0.1'}
# Qt monkey-patch #############################################################
def monkeyPatchQApplication(filename, qt=None):
"""Monkey-patch QApplication to take a snapshot and close the application.
# screenshot function ########################################################
:param str filename: The image filename where to save the snapshot.
:param str qt: The Qt binding to patch.
This MUST be the same as the one used by the script
for which to take a snapshot.
In: 'PyQt4', 'PyQt5', 'PySide2' or None (the default).
If None, it will try to use PyQt4, then PySide2 and
finally PyQt4.
"""
def makescreenshot(script_or_module, filename):
# Probe Qt binding
if qt is None:
try:
import PyQt4.QtCore # noqa
qt = 'PyQt4'
except ImportError:
try:
import PySide2.QtCore # noqa
qt = 'PySide2'
except ImportError:
try:
import PyQt5.QtCore # noqa
qt = 'PyQt5'
except ImportError:
raise RuntimeError('Cannot find any supported Qt binding.')
if qt == 'PyQt4':
from PyQt4.QtGui import QApplication, QPixmap
from PyQt4.QtCore import QTimer
import PyQt4.QtGui as _QApplicationPackage
if qt.BINDING == 'PyQt4':
def grabWindow(winID):
return QPixmap.grabWindow(winID)
elif qt == 'PyQt5':
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QTimer
import PyQt5.QtWidgets as _QApplicationPackage
return qt.QPixmap.grabWindow(winID)
elif qt.BINDING in('PyQt5', 'PySide2'):
def grabWindow(winID):
screen = QApplication.primaryScreen()
screen = qt.QApplication.primaryScreen()
return screen.grabWindow(winID)
elif qt == 'PySide2':
from PySide2.QtGui import QApplication, QPixmap
from PySide2.QtCore import QTimer
import PySide2.QtGui as _QApplicationPackage
def grabWindow(winID):
return QPixmap.grabWindow(winID)
else:
raise ValueError('Unsupported Qt binding: %s' % qt)
_logger.info('Using Qt bindings: %s', qt)
class _QApplication(QApplication):
_TIMEOUT = 1000.
_FILENAME = filename
def _grabActiveWindowAndClose(self):
activeWindow = QApplication.activeWindow()
if activeWindow is not None:
if activeWindow.isVisible():
pixmap = grabWindow(activeWindow.winId())
saveOK = pixmap.save(self._FILENAME)
if not saveOK:
_logger.error(
'Cannot save snapshot to %s', self._FILENAME)
else:
_logger.error('activeWindow is not visible.')
self.quit()
global _count
_count = 5
global _TIMEOUT
_TIMEOUT = 2000.
app = qt.QApplication.instance() or qt.QApplication([])
def _grabActiveWindowAndClose():
global _count
activeWindow = qt.QApplication.activeWindow()
if activeWindow is not None:
if activeWindow.isVisible():
pixmap = grabWindow(activeWindow.winId())
saveOK = pixmap.save(filename)
if not saveOK:
_logger.error(
'Cannot save snapshot to %s', filename)
else:
self._count -= 1
if self._count > 0:
# Only restart a timer if everything is OK
QTimer.singleShot(self._TIMEOUT,
self._grabActiveWindowAndClose)
else:
raise RuntimeError(
'Aborted: It took too long to have an active window.')
def exec_(self):
self._count = 10
QTimer.singleShot(self._TIMEOUT, self._grabActiveWindowAndClose)
return super(_QApplication, self).exec_()
_QApplicationPackage.QApplication = _QApplication
_logger.error('activeWindow is not visible.')
app.quit()
else:
_count -= 1
if _count > 0:
# Only restart a timer if everything is OK
qt.QTimer.singleShot(_TIMEOUT,
_grabActiveWindowAndClose)
else:
app.quit()
# raise('Aborted: It took too long to have an active window.')
_logger.error('Aborted: It took too long to have an active window.')
script_or_module = os.path.abspath(script_or_module)
try:
mod = SourceFileLoader("screenshotmod", script_or_module).load_module()
if hasattr(mod, 'screenshot'):
qt.QTimer.singleShot(_TIMEOUT, _grabActiveWindowAndClose)
mod.screenshot()
else:
_logger.error('no "screenshot" function found in %s' % script_or_module)
except Exception as e:
_logger.error('Fail to import %s : \n %s' % (script_or_module, e))
_logger.info('Using Qt bindings: %s', qt)
# main ########################################################################
......@@ -241,22 +198,9 @@ if __name__ == '__main__':
_logger.error(
'%s: incorrect arguments', os.path.basename(sys.argv[0]))
sys.exit(1)
#
# # Update sys.argv and sys.path
# sys.argv = [script_or_module] + extra_args
# sys.path.insert(0, os.path.abspath(os.path.dirname(script_or_module)))
# Monkey-patch Qt
monkeyPatchQApplication(args.output[0],
args.bindings if args.bindings != 'auto' else None)
# Update sys.argv and sys.path
sys.argv = [script_or_module] + extra_args
sys.path.insert(0, os.path.abspath(os.path.dirname(script_or_module)))
if args.module:
_logger.info('Running module: %s', ' '.join(sys.argv))
runpy.run_module(script_or_module, run_name='__main__')
else:
with open(script_or_module) as f:
code = f.read()
_logger.info('Running script: %s', ' '.join(sys.argv))
exec(code)
makescreenshot(script_or_module, args.output[0])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment