QtBase  v6.3.1
imagescaling.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** BSD License Usage
18 ** Alternatively, you may use this file under the terms of the BSD license
19 ** as follows:
20 **
21 ** "Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions are
23 ** met:
24 ** * Redistributions of source code must retain the above copyright
25 ** notice, this list of conditions and the following disclaimer.
26 ** * Redistributions in binary form must reproduce the above copyright
27 ** notice, this list of conditions and the following disclaimer in
28 ** the documentation and/or other materials provided with the
29 ** distribution.
30 ** * Neither the name of The Qt Company Ltd nor the names of its
31 ** contributors may be used to endorse or promote products derived
32 ** from this software without specific prior written permission.
33 **
34 **
35 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46 **
47 ** $QT_END_LICENSE$
48 **
49 ****************************************************************************/
50 #include "imagescaling.h"
51 #include "downloaddialog.h"
52 
53 #include <QNetworkReply>
54 
55 #include <qmath.h>
56 
57 #include <functional>
58 
60 {
61  setWindowTitle(tr("Image downloading and scaling example"));
62  resize(800, 600);
63 
64  addUrlsButton = new QPushButton(tr("Add URLs"));
66  connect(addUrlsButton, &QPushButton::clicked, this, &Images::process);
68 
69  cancelButton = new QPushButton(tr("Cancel"));
70  cancelButton->setEnabled(false);
72  connect(cancelButton, &QPushButton::clicked, this, &Images::cancel);
74 
75  QHBoxLayout *buttonLayout = new QHBoxLayout();
76  buttonLayout->addWidget(addUrlsButton);
77  buttonLayout->addWidget(cancelButton);
78  buttonLayout->addStretch();
79 
80  statusBar = new QStatusBar();
81 
82  imagesLayout = new QGridLayout();
83 
84  mainLayout = new QVBoxLayout();
85  mainLayout->addLayout(buttonLayout);
86  mainLayout->addLayout(imagesLayout);
87  mainLayout->addStretch();
88  mainLayout->addWidget(statusBar);
89  setLayout(mainLayout);
90 }
91 
93 {
94  cancel();
95 }
96 
99 {
100  // Clean previous state
101  replies.clear();
102 
103  if (downloadDialog->exec() == QDialog::Accepted) {
104 
105  const auto urls = downloadDialog->getUrls();
106  if (urls.empty())
107  return;
108 
109  cancelButton->setEnabled(true);
110 
111  initLayout(urls.size());
112 
113  downloadFuture = download(urls);
114  statusBar->showMessage(tr("Downloading..."));
116 
118  downloadFuture.then([this](auto) { cancelButton->setEnabled(false); })
120  [this] {
122  [this] { updateStatus(tr("Scaling...")); });
123  return scaled();
124  })
127  .then(this, [this](const QList<QImage> &scaled) {
129  updateStatus(tr("Finished"));
130  })
133  .onCanceled([this] { updateStatus(tr("Download has been canceled.")); })
134  .onFailed([this](QNetworkReply::NetworkError error) {
135  updateStatus(tr("Download finished with error: %1").arg(error));
136 
137  // Abort all pending requests
138  abortDownload();
139  })
140  .onFailed([this](const std::exception& ex) {
141  updateStatus(tr(ex.what()));
142  });
144  }
145 }
146 
149 {
150  statusBar->showMessage(tr("Canceling..."));
151 
152  downloadFuture.cancel();
153  abortDownload();
154 }
156 
160 {
163  promise->start();
165 
167  for (auto url : urls) {
169  replies.push_back(reply);
171 
173  QtFuture::connect(reply.get(), &QNetworkReply::finished).then([=] {
174  if (promise->isCanceled()) {
175  if (!promise->future().isFinished())
176  promise->finish();
177  return;
178  }
179 
181  if (!promise->future().isFinished())
182  throw reply->error();
183  }
185  promise->addResult(reply->readAll());
186 
187  // Report finished on the last download
188  if (promise->future().resultCount() == urls.size()) {
189  promise->finish();
190  }
192  }).onFailed([=] (QNetworkReply::NetworkError error) {
193  promise->setException(std::make_exception_ptr(error));
194  promise->finish();
195  }).onFailed([=] {
196  const auto ex = std::make_exception_ptr(
197  std::runtime_error("Unknown error occurred while downloading."));
198  promise->setException(ex);
199  promise->finish();
200  });
201  }
203 
205  return promise->future();
206 }
208 
211 {
213  const auto data = downloadFuture.results();
214  for (auto imgData : data) {
215  QImage image;
216  image.loadFromData(imgData);
217  if (image.isNull())
218  throw std::runtime_error("Failed to load image.");
219 
220  scaled.push_back(image.scaled(100, 100, Qt::KeepAspectRatio));
221  }
222 
223  return scaled;
224 }
226 
228 {
229  for (int i = 0; i < images.size(); ++i) {
230  labels[i]->setAlignment(Qt::AlignCenter);
231  labels[i]->setPixmap(QPixmap::fromImage(images[i]));
232  }
233 }
234 
236 {
237  // Clean old images
239  while ((child = imagesLayout->takeAt(0)) != nullptr) {
240  child->widget()->setParent(nullptr);
241  delete child;
242  }
243  labels.clear();
244 
245  // Init the images layout for the new images
246  const auto dim = int(qSqrt(qreal(count))) + 1;
247  for (int i = 0; i < dim; ++i) {
248  for (int j = 0; j < dim; ++j) {
249  QLabel *imageLabel = new QLabel;
250  imageLabel->setFixedSize(100, 100);
251  imagesLayout->addWidget(imageLabel, i, j);
252  labels.append(imageLabel);
253  }
254  }
255 }
256 
258 {
259  statusBar->showMessage(msg);
260 }
261 
263 {
264  for (auto reply : replies)
265  reply->abort();
266 }
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
const char msg[]
Definition: arch.cpp:46
FT_Error error
Definition: cffdrivr.c:657
QList< QUrl > getUrls() const
QList< QImage > scaled() const
[13]
void cancel()
[7]
void showImages(const QList< QImage > &images)
[14]
QFuture< QByteArray > download(const QList< QUrl > &urls)
[7]
void updateStatus(const QString &msg)
void abortDownload()
void initLayout(qsizetype count)
Images(QWidget *parent=nullptr)
void process()
[3]
void clicked(bool checked=false)
void addWidget(QWidget *, int stretch=0, Qt::Alignment alignment=Qt::Alignment())
void addStretch(int stretch=0)
void addLayout(QLayout *layout, int stretch=0)
virtual int exec()
Definition: qdialog.cpp:595
@ Accepted
Definition: qdialog.h:66
void cancel()
Definition: qfuture.h:100
QList< T > results() const
Definition: qfuture.h:150
QFuture< ResultType< Function > > then(Function &&function)
The QGridLayout class lays out widgets in a grid.
Definition: qgridlayout.h:57
void addWidget(QWidget *w)
Definition: qgridlayout.h:100
QLayoutItem * takeAt(int index) override
The QHBoxLayout class lines up widgets horizontally.
Definition: qboxlayout.h:114
QByteArray readAll()
Definition: qiodevice.cpp:1268
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:73
The QLabel widget provides a text or image display.
Definition: qlabel.h:56
The QLayoutItem class provides an abstract item that a QLayout manipulates.
Definition: qlayoutitem.h:61
virtual QWidget * widget() const
qsizetype size() const noexcept
Definition: qlist.h:414
void push_back(parameter_type t)
Definition: qlist.h:687
void append(parameter_type t)
Definition: qlist.h:469
void clear()
Definition: qlist.h:445
QNetworkReply * get(const QNetworkRequest &request)
NetworkError error() const
virtual void abort()=0
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Definition: qobject.cpp:2772
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Definition: qpixmap.cpp:1474
The QSharedPointer class holds a strong reference to a shared pointer.
The QStatusBar class provides a horizontal bar suitable for presenting status information.
Definition: qstatusbar.h:53
void showMessage(const QString &text, int timeout=0)
Definition: qstatusbar.cpp:536
The QString class provides a Unicode character string.
Definition: qstring.h:388
The QVBoxLayout class lines up widgets vertically.
Definition: qboxlayout.h:127
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:133
void setLayout(QLayout *)
Definition: qwidget.cpp:10146
void setParent(QWidget *parent)
Definition: qwidget.cpp:10512
void setEnabled(bool)
Definition: qwidget.cpp:3368
void setWindowTitle(const QString &)
Definition: qwidget.cpp:6119
void resize(int w, int h)
Definition: qwidget.h:916
void setFixedSize(const QSize &)
QPushButton
[1]
@ AlignCenter
Definition: qnamespace.h:188
@ KeepAspectRatio
Definition: qnamespace.h:1213
Definition: image.cpp:51
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
[3]
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
ptrdiff_t qsizetype
Definition: qglobal.h:308
auto qSqrt(T v)
Definition: qmath.h:132
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLeglImageOES image
SSL_CTX int(*) void arg)
#define tr(X)
QList< QImage > images
[6]
QUrl url("http://www.example.com/List of holidays.xml")
[0]
QLayoutItem * child
[0]
QLabel * imageLabel
[0]
QNetworkReply * reply
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent