diff --git a/examples/corelib/threads/mandelbrot/main.cpp b/examples/corelib/threads/mandelbrot/main.cpp index 9832d55514..19ea8cf417 100644 --- a/examples/corelib/threads/mandelbrot/main.cpp +++ b/examples/corelib/threads/mandelbrot/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -52,11 +52,43 @@ #include +#include + +#include +#include +#include +#include + //! [0] int main(int argc, char *argv[]) { QApplication app(argc, argv); + + QCommandLineParser parser; + parser.setApplicationDescription("Qt Mandelbrot Example"); + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption passesOption("passes", "Number of passes (1-8)", "passes"); + parser.addOption(passesOption); + parser.process(app); + + if (parser.isSet(passesOption)) { + const auto passesStr = parser.value(passesOption); + bool ok; + const int passes = passesStr.toInt(&ok); + if (!ok || passes < 1 || passes > 8) { + qWarning() << "Invalid value:" << passesStr; + return -1; + } + RenderThread::setNumPasses(passes); + } + MandelbrotWidget widget; + const auto geometry = widget.screen()->availableGeometry(); + widget.resize((2 * geometry.size()) / 3); + const auto pos = (geometry.size() - widget.size()) / 2; + widget.move(geometry.topLeft() + QPoint(pos.width(), pos.height())); + widget.show(); return app.exec(); } diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp index b0c3733b22..bb1f83482b 100644 --- a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp +++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -73,6 +73,8 @@ MandelbrotWidget::MandelbrotWidget(QWidget *parent) : pixmapScale(DefaultScale), curScale(DefaultScale) { + help = tr("Use mouse wheel or the '+' and '-' keys to zoom. " + "Press and hold left mouse button to scroll."); connect(&thread, &RenderThread::renderedImage, this, &MandelbrotWidget::updatePixmap); @@ -80,8 +82,6 @@ MandelbrotWidget::MandelbrotWidget(QWidget *parent) : #if QT_CONFIG(cursor) setCursor(Qt::CrossCursor); #endif - resize(550, 400); - } //! [1] @@ -127,8 +127,9 @@ void MandelbrotWidget::paintEvent(QPaintEvent * /* event */) } //! [8] //! [9] - QString text = tr("Use mouse wheel or the '+' and '-' keys to zoom. " - "Press and hold left mouse button to scroll."); + QString text = help; + if (!info.isEmpty()) + text += ' ' + info; QFontMetrics metrics = painter.fontMetrics(); int textWidth = metrics.horizontalAdvance(text); @@ -169,6 +170,9 @@ void MandelbrotWidget::keyPressEvent(QKeyEvent *event) case Qt::Key_Up: scroll(0, +ScrollStep); break; + case Qt::Key_Q: + close(); + break; default: QWidget::keyPressEvent(event); } @@ -226,6 +230,8 @@ void MandelbrotWidget::updatePixmap(const QImage &image, double scaleFactor) if (!lastDragPos.isNull()) return; + info = image.text(RenderThread::infoKey()); + pixmap = QPixmap::fromImage(image); pixmapOffset = QPoint(); lastDragPos = QPoint(); diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.h b/examples/corelib/threads/mandelbrot/mandelbrotwidget.h index cb40962535..956ffc10a8 100644 --- a/examples/corelib/threads/mandelbrot/mandelbrotwidget.h +++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -86,6 +86,8 @@ private: QPixmap pixmap; QPoint pixmapOffset; QPoint lastDragPos; + QString help; + QString info; double centerX; double centerY; double pixmapScale; diff --git a/examples/corelib/threads/mandelbrot/renderthread.cpp b/examples/corelib/threads/mandelbrot/renderthread.cpp index 4d2009471c..1f2af3b999 100644 --- a/examples/corelib/threads/mandelbrot/renderthread.cpp +++ b/examples/corelib/threads/mandelbrot/renderthread.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -51,8 +51,14 @@ #include "renderthread.h" #include + +#include +#include + #include +int RenderThread::numPasses = 8; + //! [0] RenderThread::RenderThread(QObject *parent) : QThread(parent) @@ -98,6 +104,7 @@ void RenderThread::render(double centerX, double centerY, double scaleFactor, //! [3] void RenderThread::run() { + QElapsedTimer timer; forever { mutex.lock(); const double devicePixelRatio = this->devicePixelRatio; @@ -116,13 +123,14 @@ void RenderThread::run() QImage image(resultSize, QImage::Format_RGB32); image.setDevicePixelRatio(devicePixelRatio); - const int NumPasses = 8; int pass = 0; - while (pass < NumPasses) { + while (pass < numPasses) { const int MaxIterations = (1 << (2 * pass + 6)) + 32; const int Limit = 4; bool allBlack = true; + timer.restart(); + for (int y = -halfHeight; y < halfHeight; ++y) { if (restart) break; @@ -165,8 +173,20 @@ void RenderThread::run() if (allBlack && pass == 0) { pass = 4; } else { - if (!restart) + if (!restart) { + QString message; + QTextStream str(&message); + str << " Pass " << (pass + 1) << '/' << numPasses + << ", max iterations: " << MaxIterations << ", time: "; + const auto elapsed = timer.elapsed(); + if (elapsed > 2000) + str << (elapsed / 1000) << 's'; + else + str << elapsed << "ms"; + image.setText(infoKey(), message); + emit renderedImage(image, requestedScaleFactor); + } //! [5] //! [6] ++pass; } diff --git a/examples/corelib/threads/mandelbrot/renderthread.h b/examples/corelib/threads/mandelbrot/renderthread.h index 6174e0ed3d..7bbd9ae056 100644 --- a/examples/corelib/threads/mandelbrot/renderthread.h +++ b/examples/corelib/threads/mandelbrot/renderthread.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -72,6 +72,10 @@ public: void render(double centerX, double centerY, double scaleFactor, QSize resultSize, double devicePixelRatio); + static void setNumPasses(int n) { numPasses = n; } + + static QString infoKey() { return QStringLiteral("info"); } + signals: void renderedImage(const QImage &image, double scaleFactor); @@ -88,6 +92,7 @@ private: double scaleFactor; double devicePixelRatio; QSize resultSize; + static int numPasses; bool restart = false; bool abort = false;