Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
payno
id06workflow
Commits
3840a32b
Commit
3840a32b
authored
Nov 20, 2018
by
payno
Browse files
[doc] update the snapshot qt directive
parent
5787dc81
Changes
1
Hide whitespace changes
Inline
Side-by-side
doc/ext/snapshotqt_directive.py
View file @
3840a32b
...
...
@@ -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
])
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment