Polish the image gestures example.
- Add a command line parser to properly evaluate help option and directory argument, add options to disable gestures. - Add logging category so that the user can actually see what is happening. - Scale large images. - Use qreal instead of float. - Minor polishing: set window title, position file dialog at pictures location. Task-number: QTBUG-37759 Task-number: QTBUG-37203 Change-Id: Ibaf54a13034b150386a8aee476f83a9eba298298 Reviewed-by: Indrajit Tapadar <indrajit.tapadar@digia.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
This commit is contained in:
parent
4cb0e96505
commit
c0701f3789
@ -1,7 +1,7 @@
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
@ -43,6 +43,8 @@
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
Q_LOGGING_CATEGORY(lcExample, "qt.examples.imagegestures")
|
||||
|
||||
//! [constructor]
|
||||
ImageWidget::ImageWidget(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
@ -55,15 +57,17 @@ ImageWidget::ImageWidget(QWidget *parent)
|
||||
|
||||
{
|
||||
setMinimumSize(QSize(100,100));
|
||||
|
||||
//! [enable gestures]
|
||||
grabGesture(Qt::PanGesture);
|
||||
grabGesture(Qt::PinchGesture);
|
||||
grabGesture(Qt::SwipeGesture);
|
||||
//! [enable gestures]
|
||||
}
|
||||
//! [constructor]
|
||||
|
||||
void ImageWidget::grabGestures(const QList<Qt::GestureType> &gestures)
|
||||
{
|
||||
//! [enable gestures]
|
||||
foreach (Qt::GestureType gesture, gestures)
|
||||
grabGesture(gesture);
|
||||
//! [enable gestures]
|
||||
}
|
||||
|
||||
//! [event handler]
|
||||
bool ImageWidget::event(QEvent *event)
|
||||
{
|
||||
@ -77,10 +81,10 @@ void ImageWidget::paintEvent(QPaintEvent*)
|
||||
{
|
||||
QPainter p(this);
|
||||
|
||||
float iw = currentImage.width();
|
||||
float ih = currentImage.height();
|
||||
float wh = height();
|
||||
float ww = width();
|
||||
const qreal iw = currentImage.width();
|
||||
const qreal ih = currentImage.height();
|
||||
const qreal wh = height();
|
||||
const qreal ww = width();
|
||||
|
||||
p.translate(ww/2, wh/2);
|
||||
p.translate(horizontalOffset, verticalOffset);
|
||||
@ -98,11 +102,13 @@ void ImageWidget::mouseDoubleClickEvent(QMouseEvent *)
|
||||
verticalOffset = 0;
|
||||
horizontalOffset = 0;
|
||||
update();
|
||||
qCDebug(lcExample) << "reset on mouse double click";
|
||||
}
|
||||
|
||||
//! [gesture event handler]
|
||||
bool ImageWidget::gestureEvent(QGestureEvent *event)
|
||||
{
|
||||
qCDebug(lcExample) << "gestureEvent():" << event->gestures().size();
|
||||
if (QGesture *swipe = event->gesture(Qt::SwipeGesture))
|
||||
swipeTriggered(static_cast<QSwipeGesture *>(swipe));
|
||||
else if (QGesture *pan = event->gesture(Qt::PanGesture))
|
||||
@ -126,6 +132,7 @@ void ImageWidget::panTriggered(QPanGesture *gesture)
|
||||
}
|
||||
#endif
|
||||
QPointF delta = gesture->delta();
|
||||
qCDebug(lcExample) << "panTriggered():" << delta;
|
||||
horizontalOffset += delta.x();
|
||||
verticalOffset += delta.y();
|
||||
update();
|
||||
@ -135,13 +142,16 @@ void ImageWidget::pinchTriggered(QPinchGesture *gesture)
|
||||
{
|
||||
QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags();
|
||||
if (changeFlags & QPinchGesture::RotationAngleChanged) {
|
||||
qreal value = gesture->property("rotationAngle").toReal();
|
||||
qreal lastValue = gesture->property("lastRotationAngle").toReal();
|
||||
rotationAngle += value - lastValue;
|
||||
const qreal value = gesture->property("rotationAngle").toReal();
|
||||
const qreal lastValue = gesture->property("lastRotationAngle").toReal();
|
||||
const qreal rotationAngleDelta = value - lastValue;
|
||||
rotationAngle += rotationAngleDelta;
|
||||
qCDebug(lcExample) << "pinchTriggered(): rotation by" << rotationAngleDelta << rotationAngle;
|
||||
}
|
||||
if (changeFlags & QPinchGesture::ScaleFactorChanged) {
|
||||
qreal value = gesture->property("scaleFactor").toReal();
|
||||
currentStepScaleFactor = value;
|
||||
qCDebug(lcExample) << "pinchTriggered(): " << currentStepScaleFactor;
|
||||
}
|
||||
if (gesture->state() == Qt::GestureFinished) {
|
||||
scaleFactor *= currentStepScaleFactor;
|
||||
@ -155,10 +165,13 @@ void ImageWidget::swipeTriggered(QSwipeGesture *gesture)
|
||||
{
|
||||
if (gesture->state() == Qt::GestureFinished) {
|
||||
if (gesture->horizontalDirection() == QSwipeGesture::Left
|
||||
|| gesture->verticalDirection() == QSwipeGesture::Up)
|
||||
|| gesture->verticalDirection() == QSwipeGesture::Up) {
|
||||
qCDebug(lcExample) << "swipeTriggered(): swipe to previous";
|
||||
goPrevImage();
|
||||
else
|
||||
} else {
|
||||
qCDebug(lcExample) << "swipeTriggered(): swipe to next";
|
||||
goNextImage();
|
||||
}
|
||||
update();
|
||||
}
|
||||
}
|
||||
@ -184,17 +197,22 @@ void ImageWidget::openDirectory(const QString &path)
|
||||
|
||||
QImage ImageWidget::loadImage(const QString &fileName)
|
||||
{
|
||||
qDebug() << position << files << fileName;
|
||||
QImageReader reader(fileName);
|
||||
qCDebug(lcExample) << "loading" << QDir::toNativeSeparators(fileName) << position << '/' << files.size();
|
||||
if (!reader.canRead()) {
|
||||
qDebug() << fileName << ": can't load image";
|
||||
qCWarning(lcExample) << QDir::toNativeSeparators(fileName) << ": can't load image";
|
||||
return QImage();
|
||||
}
|
||||
|
||||
QImage image;
|
||||
if (!reader.read(&image)) {
|
||||
qDebug() << fileName << ": corrupted image";
|
||||
qCWarning(lcExample) << QDir::toNativeSeparators(fileName) << ": corrupted image: " << reader.errorString();
|
||||
return QImage();
|
||||
}
|
||||
const QSize maximumSize(2000, 2000); // Reduce in case someone has large photo images.
|
||||
if (image.size().width() > maximumSize.width() || image.height() > maximumSize.height())
|
||||
image = image.scaled(maximumSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
return image;
|
||||
}
|
||||
|
||||
@ -238,7 +256,7 @@ void ImageWidget::goToImage(int index)
|
||||
return;
|
||||
|
||||
if (index < 0 || index >= files.size()) {
|
||||
qDebug() << "goToImage: invalid index: " << index;
|
||||
qCWarning(lcExample) << "goToImage: invalid index: " << index;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
@ -52,6 +52,8 @@ class QPinchGesture;
|
||||
class QSwipeGesture;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcExample)
|
||||
|
||||
//! [class definition begin]
|
||||
class ImageWidget : public QWidget
|
||||
{
|
||||
@ -60,6 +62,7 @@ class ImageWidget : public QWidget
|
||||
public:
|
||||
ImageWidget(QWidget *parent = 0);
|
||||
void openDirectory(const QString &path);
|
||||
void grabGestures(const QList<Qt::GestureType> &gestures);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event);
|
||||
@ -88,11 +91,11 @@ private:
|
||||
QImage prevImage, nextImage;
|
||||
QImage currentImage;
|
||||
|
||||
float horizontalOffset;
|
||||
float verticalOffset;
|
||||
float rotationAngle;
|
||||
float scaleFactor;
|
||||
float currentStepScaleFactor;
|
||||
qreal horizontalOffset;
|
||||
qreal verticalOffset;
|
||||
qreal rotationAngle;
|
||||
qreal scaleFactor;
|
||||
qreal currentStepScaleFactor;
|
||||
//! [class definition end]
|
||||
};
|
||||
//! [class definition end]
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
@ -42,17 +42,86 @@
|
||||
|
||||
#include "mainwidget.h"
|
||||
|
||||
static void showHelp(QCommandLineParser &parser, const QString errorMessage = QString())
|
||||
{
|
||||
QString text;
|
||||
QTextStream str(&text);
|
||||
str << "<html><head/><body>";
|
||||
if (!errorMessage.isEmpty())
|
||||
str << "<p>" << errorMessage << "</p>";
|
||||
str << "<pre>" << parser.helpText() << "</pre></body></html>";
|
||||
QMessageBox box(errorMessage.isEmpty() ? QMessageBox::Information : QMessageBox::Warning,
|
||||
QGuiApplication::applicationDisplayName(), text,
|
||||
QMessageBox::Ok);
|
||||
box.setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
box.exec();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
|
||||
QCoreApplication::setApplicationName(QStringLiteral("imagegestures"));
|
||||
QGuiApplication::setApplicationDisplayName(QStringLiteral("Image Gestures Example"));
|
||||
|
||||
QCommandLineParser commandLineParser;
|
||||
const QCommandLineOption disablePanOption("no-pan", "Disable pan gesture");
|
||||
commandLineParser.addOption(disablePanOption);
|
||||
const QCommandLineOption disablePinchOption("no-pinch", "Disable pinch gesture");
|
||||
commandLineParser.addOption(disablePinchOption);
|
||||
const QCommandLineOption disableSwipeOption("no-swipe", "Disable swipe gesture");
|
||||
commandLineParser.addOption(disableSwipeOption);
|
||||
const QCommandLineOption helpOption = commandLineParser.addHelpOption();
|
||||
commandLineParser.addPositionalArgument(QStringLiteral("Directory"),
|
||||
QStringLiteral("Directory to display"));
|
||||
|
||||
const QString description = QGuiApplication::applicationDisplayName()
|
||||
+ QLatin1String("\n\nEnable \"debug\" on the logging category \"qt.examples.imagegestures\" in order to\n"
|
||||
"in order to obtain verbose information about Qt's gesture event processing,\n"
|
||||
"for example by setting the environment variables QT_LOGGING_RULES to\n"
|
||||
"qt.examples.imagegestures.debug=true\n");
|
||||
commandLineParser.setApplicationDescription(description);
|
||||
|
||||
if (!commandLineParser.parse(QCoreApplication::arguments())) {
|
||||
showHelp(commandLineParser, commandLineParser.errorText());
|
||||
return -1;
|
||||
}
|
||||
if (commandLineParser.isSet(helpOption)) {
|
||||
showHelp(commandLineParser);
|
||||
return 0;
|
||||
}
|
||||
|
||||
QStringList arguments = commandLineParser.positionalArguments();
|
||||
if (!arguments.isEmpty() && !QFileInfo(arguments.front()).isDir()) {
|
||||
showHelp(commandLineParser,
|
||||
QLatin1Char('"') + QDir::toNativeSeparators(arguments.front())
|
||||
+ QStringLiteral("\" is not a directory."));
|
||||
return -1;
|
||||
}
|
||||
|
||||
QList<Qt::GestureType> gestures;
|
||||
if (!commandLineParser.isSet(disablePanOption))
|
||||
gestures << Qt::PanGesture;
|
||||
if (!commandLineParser.isSet(disablePinchOption))
|
||||
gestures << Qt::PinchGesture;
|
||||
if (!commandLineParser.isSet(disableSwipeOption))
|
||||
gestures << Qt::SwipeGesture;
|
||||
|
||||
MainWidget w;
|
||||
w.grabGestures(gestures);
|
||||
w.show();
|
||||
|
||||
if (QApplication::arguments().size() > 1)
|
||||
w.openDirectory(QApplication::arguments().at(1));
|
||||
else
|
||||
w.openDirectory(QFileDialog::getExistingDirectory(0, "Select image folder"));
|
||||
if (arguments.isEmpty()) {
|
||||
const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
|
||||
const QString directory =
|
||||
QFileDialog::getExistingDirectory(&w, "Select image folder",
|
||||
picturesLocations.isEmpty() ? QString() : picturesLocations.front());
|
||||
if (directory.isEmpty())
|
||||
return 0;
|
||||
arguments.append(directory);
|
||||
}
|
||||
|
||||
w.openDirectory(arguments.front());
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
@ -41,15 +41,28 @@
|
||||
#include "imagewidget.h"
|
||||
#include "mainwidget.h"
|
||||
|
||||
#include <QScreen>
|
||||
#include <QGuiApplication>
|
||||
#include <QDir>
|
||||
|
||||
MainWidget::MainWidget(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, imageWidget(new ImageWidget(this))
|
||||
{
|
||||
resize(400, 300);
|
||||
imageWidget = new ImageWidget(this);
|
||||
setCentralWidget(imageWidget);
|
||||
const QRect screenGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
QRect geometry(QPoint(0, 0), QSize(screenGeometry.width() * 3 / 4, screenGeometry.height() * 3 / 4));
|
||||
geometry.moveCenter(screenGeometry.center());
|
||||
setGeometry(geometry);
|
||||
}
|
||||
|
||||
void MainWidget::openDirectory(const QString &path)
|
||||
{
|
||||
setWindowTitle(QDir::toNativeSeparators(path));
|
||||
imageWidget->openDirectory(path);
|
||||
}
|
||||
|
||||
void MainWidget::grabGestures(const QList<Qt::GestureType> &gestures)
|
||||
{
|
||||
imageWidget->grabGestures(gestures);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
@ -51,6 +51,7 @@ class MainWidget : public QMainWindow
|
||||
|
||||
public:
|
||||
MainWidget(QWidget *parent = 0);
|
||||
void grabGestures(const QList<Qt::GestureType> &gestures);
|
||||
|
||||
public slots:
|
||||
void openDirectory(const QString &path);
|
||||
|
Loading…
Reference in New Issue
Block a user