on xenial help sign in
Make saving screenshots really async
a205b3eLukáš Tinkl
plugins/ScreenGrabber/screengrabber.cpp+18−8
@@ -23,23 +23,27 @@
23#include <QtGui/QImage>
23#include <QtGui/QImage>
24#include <QtGui/QGuiApplication>
24#include <QtGui/QGuiApplication>
25#include <QtQuick/QQuickWindow>
25#include <QtQuick/QQuickWindow>
26−#include <QtConcurrent/QtConcurrentRun>
27
26
28#include <QDebug>
27#include <QDebug>
29
28
30−bool saveScreenshot(const QImage &screenshot, const QString &filename, const QString &format, int quality)
29+QString saveScreenshot(const QImage &screenshot, const QString &filename, const QString &format, int quality)
31{
30{
32− if (!screenshot.save(filename, format.toLatin1().data(), quality)) {
31+ if (screenshot.save(filename, format.toLatin1().data(), quality)) {
32+ return filename;
33+ } else {
33 qWarning() << "ScreenGrabber: failed to save snapshot!";
34 qWarning() << "ScreenGrabber: failed to save snapshot!";
34− return false;
35 }
35 }
36−
37− return true;
36+ return QString();
38}
37}
39
38
40ScreenGrabber::ScreenGrabber(QObject *parent)
39ScreenGrabber::ScreenGrabber(QObject *parent)
41 : QObject(parent)
40 : QObject(parent)
42{
41{
42+ QObject::connect(&m_watcher,
43+ &QFutureWatcher<QString>::finished,
44+ this,
45+ &ScreenGrabber::onScreenshotSaved);
46+
43 QDir screenshotsDir;
47 QDir screenshotsDir;
44 if (qEnvironmentVariableIsSet("UNITY_TESTING")) {
48 if (qEnvironmentVariableIsSet("UNITY_TESTING")) {
45 qDebug() << "Using test environment";
49 qDebug() << "Using test environment";
@@ -85,8 +89,14 @@ void ScreenGrabber::captureAndSave(int angle)
85 const QImage screenshot = main_window->grabWindow().transformed(QTransform().rotate(angle));
89 const QImage screenshot = main_window->grabWindow().transformed(QTransform().rotate(angle));
86 const QString filename = makeFileName();
90 const QString filename = makeFileName();
87 qDebug() << "Saving screenshot to" << filename;
91 qDebug() << "Saving screenshot to" << filename;
88− auto saveOp = QtConcurrent::run(saveScreenshot, screenshot, filename, getFormat(), screenshotQuality);
92+ QFuture<QString> saveFuture(QtConcurrent::run(saveScreenshot, screenshot, filename, getFormat(), screenshotQuality));
89− if (saveOp.result()) {
93+ m_watcher.setFuture(saveFuture);
94+}
95+
96+void ScreenGrabber::onScreenshotSaved()
97+{
98+ const QString filename = m_watcher.future().result();
99+ if (!filename.isEmpty()) {
90 Q_EMIT screenshotSaved(filename);
100 Q_EMIT screenshotSaved(filename);
91 }
101 }
92}
102}
plugins/ScreenGrabber/screengrabber.h+5
@@ -19,6 +19,7 @@
19
19
20#include <QObject>
20#include <QObject>
21#include <QString>
21#include <QString>
22+#include <QtConcurrent>
22
23
23class ScreenGrabber: public QObject
24class ScreenGrabber: public QObject
24{
25{
@@ -34,11 +35,15 @@ public Q_SLOTS:
34Q_SIGNALS:
35Q_SIGNALS:
35 void screenshotSaved(const QString &filename);
36 void screenshotSaved(const QString &filename);
36
37
38+private Q_SLOTS:
39+ void onScreenshotSaved();
40+
37private:
41private:
38 QString makeFileName() const;
42 QString makeFileName() const;
39 QString getFormat() const;
43 QString getFormat() const;
40 QString fileNamePrefix;
44 QString fileNamePrefix;
41 int screenshotQuality = -1; // default quality for the format
45 int screenshotQuality = -1; // default quality for the format
46+ QFutureWatcher<QString> m_watcher;
42};
47};
43
48
44#endif
49#endif
tests/plugins/ScreenGrabber/CMakeLists.txt+1−1
@@ -9,6 +9,6 @@ add_definitions(
9add_definitions(-DBUILT_PLUGINS_DIR="${CMAKE_BINARY_DIR}/plugins")
9add_definitions(-DBUILT_PLUGINS_DIR="${CMAKE_BINARY_DIR}/plugins")
10
10
11add_executable(ScreenGrabberTestExec ScreenGrabberTest.cpp ${CMAKE_SOURCE_DIR}/plugins/ScreenGrabber/screengrabber.cpp)
11add_executable(ScreenGrabberTestExec ScreenGrabberTest.cpp ${CMAKE_SOURCE_DIR}/plugins/ScreenGrabber/screengrabber.cpp)
12−qt5_use_modules(ScreenGrabberTestExec Test Quick)
12+qt5_use_modules(ScreenGrabberTestExec Test Quick Concurrent)
13target_link_libraries(ScreenGrabberTestExec ${Qt5Quick_LIBRARIES} ScreenGrabber-qml)
13target_link_libraries(ScreenGrabberTestExec ${Qt5Quick_LIBRARIES} ScreenGrabber-qml)
14add_unity8_uitest(ScreenGrabber ScreenGrabberTestExec DEPENDS ScreenGrabber-qml)
14add_unity8_uitest(ScreenGrabber ScreenGrabberTestExec DEPENDS ScreenGrabber-qml)
tests/plugins/ScreenGrabber/ScreenGrabberTest.cpp+1
@@ -59,6 +59,7 @@ private Q_SLOTS:
59 {
59 {
60 QSignalSpy grabberSpy(m_grabber, &ScreenGrabber::screenshotSaved);
60 QSignalSpy grabberSpy(m_grabber, &ScreenGrabber::screenshotSaved);
61 m_grabber->captureAndSave(90); // rotate by 90°
61 m_grabber->captureAndSave(90); // rotate by 90°
62+ QTRY_VERIFY(grabberSpy.count() == 1);
62 const QVariantList args = grabberSpy.takeFirst();
63 const QVariantList args = grabberSpy.takeFirst();
63 const QString filename = args.first().toString();
64 const QString filename = args.first().toString();
64 QVERIFY(!filename.isEmpty());
65 QVERIFY(!filename.isEmpty());