diff options
Diffstat (limited to 'tests/manual/examples/widgets/itemviews/pixelator')
11 files changed, 538 insertions, 0 deletions
diff --git a/tests/manual/examples/widgets/itemviews/pixelator/CMakeLists.txt b/tests/manual/examples/widgets/itemviews/pixelator/CMakeLists.txt new file mode 100644 index 0000000000..0a2671b13c --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/CMakeLists.txt @@ -0,0 +1,58 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(pixelator LANGUAGES CXX) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/pixelator") + +find_package(Qt6 + REQUIRED COMPONENTS Core Gui Widgets + OPTIONAL_COMPONENTS PrintSupport +) + +qt_standard_project_setup() + +qt_add_executable(pixelator + imagemodel.cpp imagemodel.h + main.cpp + mainwindow.cpp mainwindow.h + pixeldelegate.cpp pixeldelegate.h +) + +set_target_properties(pixelator PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(pixelator PRIVATE + Qt6::Core + Qt6::Gui + Qt6::Widgets +) + +if(TARGET Qt6::PrintSupport) + target_link_libraries(pixelator PRIVATE Qt6::PrintSupport) +endif() + +# Resources: +set(images_resource_files + "images/qt.png" +) + +qt_add_resources(pixelator "images" + PREFIX + "/" + FILES + ${images_resource_files} +) + +install(TARGETS pixelator + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/tests/manual/examples/widgets/itemviews/pixelator/imagemodel.cpp b/tests/manual/examples/widgets/itemviews/pixelator/imagemodel.cpp new file mode 100644 index 0000000000..6b5b866522 --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/imagemodel.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "imagemodel.h" + +//! [0] +ImageModel::ImageModel(QObject *parent) + : QAbstractTableModel(parent) +{ +} +//! [0] + +//! [1] +void ImageModel::setImage(const QImage &image) +{ + beginResetModel(); + modelImage = image; + endResetModel(); +} +//! [1] + +//! [2] +int ImageModel::rowCount(const QModelIndex & /* parent */) const +{ + return modelImage.height(); +} + +int ImageModel::columnCount(const QModelIndex & /* parent */) const +//! [2] //! [3] +{ + return modelImage.width(); +} +//! [3] + +//! [4] +QVariant ImageModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || role != Qt::DisplayRole) + return QVariant(); + return qGray(modelImage.pixel(index.column(), index.row())); +} +//! [4] + +//! [5] +QVariant ImageModel::headerData(int /* section */, + Qt::Orientation /* orientation */, + int role) const +{ + if (role == Qt::SizeHintRole) + return QSize(1, 1); + return QVariant(); +} +//! [5] diff --git a/tests/manual/examples/widgets/itemviews/pixelator/imagemodel.h b/tests/manual/examples/widgets/itemviews/pixelator/imagemodel.h new file mode 100644 index 0000000000..050ac6b790 --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/imagemodel.h @@ -0,0 +1,31 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef IMAGEMODEL_H +#define IMAGEMODEL_H + +#include <QAbstractTableModel> +#include <QImage> + +//! [0] +class ImageModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + ImageModel(QObject *parent = nullptr); + + void setImage(const QImage &image); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + +private: + QImage modelImage; +}; +//! [0] + +#endif // IMAGEMODEL_H diff --git a/tests/manual/examples/widgets/itemviews/pixelator/images.qrc b/tests/manual/examples/widgets/itemviews/pixelator/images.qrc new file mode 100644 index 0000000000..c105e13895 --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/images.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>images/qt.png</file> +</qresource> +</RCC> diff --git a/tests/manual/examples/widgets/itemviews/pixelator/images/qt.png b/tests/manual/examples/widgets/itemviews/pixelator/images/qt.png Binary files differnew file mode 100644 index 0000000000..dd197cb59c --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/images/qt.png diff --git a/tests/manual/examples/widgets/itemviews/pixelator/main.cpp b/tests/manual/examples/widgets/itemviews/pixelator/main.cpp new file mode 100644 index 0000000000..26783b02fc --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/main.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QApplication> + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MainWindow window; + window.show(); + window.openImage(":/images/qt.png"); + return app.exec(); +} diff --git a/tests/manual/examples/widgets/itemviews/pixelator/mainwindow.cpp b/tests/manual/examples/widgets/itemviews/pixelator/mainwindow.cpp new file mode 100644 index 0000000000..42f0a43844 --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/mainwindow.cpp @@ -0,0 +1,214 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "mainwindow.h" +#include "imagemodel.h" +#include "pixeldelegate.h" + +#include <QtWidgets> +#if defined(QT_PRINTSUPPORT_LIB) +#include <QtPrintSupport/qtprintsupportglobal.h> +#if QT_CONFIG(printdialog) +#include <QPrinter> +#include <QPrintDialog> +#endif +#endif + +//! [0] +MainWindow::MainWindow() +{ +//! [0] + currentPath = QDir::homePath(); + model = new ImageModel(this); + + QWidget *centralWidget = new QWidget; + +//! [1] + view = new QTableView; + view->setShowGrid(false); + view->horizontalHeader()->hide(); + view->verticalHeader()->hide(); + view->horizontalHeader()->setMinimumSectionSize(1); + view->verticalHeader()->setMinimumSectionSize(1); + view->setModel(model); +//! [1] + +//! [2] + PixelDelegate *delegate = new PixelDelegate(this); + view->setItemDelegate(delegate); +//! [2] + +//! [3] + QLabel *pixelSizeLabel = new QLabel(tr("Pixel size:")); + QSpinBox *pixelSizeSpinBox = new QSpinBox; + pixelSizeSpinBox->setMinimum(4); + pixelSizeSpinBox->setMaximum(32); + pixelSizeSpinBox->setValue(12); +//! [3] + + QMenu *fileMenu = new QMenu(tr("&File"), this); + QAction *openAction = fileMenu->addAction(tr("&Open...")); + openAction->setShortcuts(QKeySequence::Open); + + printAction = fileMenu->addAction(tr("&Print...")); + printAction->setEnabled(false); + printAction->setShortcut(QKeySequence::Print); + + QAction *quitAction = fileMenu->addAction(tr("E&xit")); + quitAction->setShortcuts(QKeySequence::Quit); + + QMenu *helpMenu = new QMenu(tr("&Help"), this); + QAction *aboutAction = helpMenu->addAction(tr("&About")); + + menuBar()->addMenu(fileMenu); + menuBar()->addSeparator(); + menuBar()->addMenu(helpMenu); + + connect(openAction, &QAction::triggered, this, &MainWindow::chooseImage); + connect(printAction, &QAction::triggered, this, &MainWindow::printImage); + connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); + connect(aboutAction, &QAction::triggered, this, &MainWindow::showAboutBox); +//! [4] + connect(pixelSizeSpinBox, &QSpinBox::valueChanged, + delegate, &PixelDelegate::setPixelSize); + connect(pixelSizeSpinBox, &QSpinBox::valueChanged, + this, &MainWindow::updateView); +//! [4] + + QHBoxLayout *controlsLayout = new QHBoxLayout; + controlsLayout->addWidget(pixelSizeLabel); + controlsLayout->addWidget(pixelSizeSpinBox); + controlsLayout->addStretch(1); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(view); + mainLayout->addLayout(controlsLayout); + centralWidget->setLayout(mainLayout); + + setCentralWidget(centralWidget); + + setWindowTitle(tr("Pixelator")); + resize(640, 480); +//! [5] +} +//! [5] + +void MainWindow::chooseImage() +{ + QString fileName = QFileDialog::getOpenFileName(this, + tr("Choose an image"), currentPath, "*"); + + if (!fileName.isEmpty()) + openImage(fileName); +} + +void MainWindow::openImage(const QString &fileName) +{ + QImage image; + + if (image.load(fileName)) { + model->setImage(image); + if (!fileName.startsWith(":/")) { + currentPath = fileName; + setWindowTitle(tr("%1 - Pixelator").arg(currentPath)); + } + + printAction->setEnabled(true); + updateView(); + } +} + +void MainWindow::printImage() +{ +#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog) + if (model->rowCount(QModelIndex())*model->columnCount(QModelIndex()) > 90000) { + QMessageBox::StandardButton answer; + answer = QMessageBox::question(this, tr("Large Image Size"), + tr("The printed image may be very large. Are you sure that " + "you want to print it?"), + QMessageBox::Yes | QMessageBox::No); + if (answer == QMessageBox::No) + return; + } + + QPrinter printer(QPrinter::HighResolution); + + QPrintDialog dlg(&printer, this); + dlg.setWindowTitle(tr("Print Image")); + + if (dlg.exec() != QDialog::Accepted) { + return; + } + + QPainter painter; + painter.begin(&printer); + + int rows = model->rowCount(QModelIndex()); + int columns = model->columnCount(QModelIndex()); + int sourceWidth = (columns + 1) * ItemSize; + int sourceHeight = (rows + 1) * ItemSize; + + painter.save(); + + double xscale = printer.pageRect(QPrinter::DevicePixel).width() / double(sourceWidth); + double yscale = printer.pageRect(QPrinter::DevicePixel).height() / double(sourceHeight); + double scale = qMin(xscale, yscale); + + painter.translate(printer.paperRect(QPrinter::DevicePixel).x() + printer.pageRect(QPrinter::DevicePixel).width() / 2, + printer.paperRect(QPrinter::DevicePixel).y() + printer.pageRect(QPrinter::DevicePixel).height() / 2); + painter.scale(scale, scale); + painter.translate(-sourceWidth / 2, -sourceHeight / 2); + + QStyleOptionViewItem option; + QModelIndex parent = QModelIndex(); + + QProgressDialog progress(tr("Printing..."), tr("Cancel"), 0, rows, this); + progress.setWindowModality(Qt::ApplicationModal); + float y = ItemSize / 2; + + for (int row = 0; row < rows; ++row) { + progress.setValue(row); + qApp->processEvents(); + if (progress.wasCanceled()) + break; + + float x = ItemSize / 2; + + for (int column = 0; column < columns; ++column) { + option.rect = QRect(int(x), int(y), ItemSize, ItemSize); + view->itemDelegate()->paint(&painter, option, + model->index(row, column, parent)); + x = x + ItemSize; + } + y = y + ItemSize; + } + progress.setValue(rows); + + painter.restore(); + painter.end(); + + if (progress.wasCanceled()) { + QMessageBox::information(this, tr("Printing canceled"), + tr("The printing process was canceled."), QMessageBox::Cancel); + } +#else + QMessageBox::information(this, tr("Printing canceled"), + tr("Printing is not supported on this Qt build"), QMessageBox::Cancel); +#endif +} + +void MainWindow::showAboutBox() +{ + QMessageBox::about(this, tr("About the Pixelator example"), + tr("This example demonstrates how a standard view and a custom\n" + "delegate can be used to produce a specialized representation\n" + "of data in a simple custom model.")); +} + +//! [6] +void MainWindow::updateView() +{ + view->resizeColumnsToContents(); + view->resizeRowsToContents(); +} +//! [6] diff --git a/tests/manual/examples/widgets/itemviews/pixelator/mainwindow.h b/tests/manual/examples/widgets/itemviews/pixelator/mainwindow.h new file mode 100644 index 0000000000..9929e2f5af --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/mainwindow.h @@ -0,0 +1,37 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> + +class ImageModel; +QT_BEGIN_NAMESPACE +class QAction; +class QTableView; +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + + void openImage(const QString &fileName); + +public slots: + void chooseImage(); + void printImage(); + void showAboutBox(); + void updateView(); + +private: + ImageModel *model; + QAction *printAction; + QString currentPath; + QTableView *view; +}; + +#endif // MAINWINDOW_H diff --git a/tests/manual/examples/widgets/itemviews/pixelator/pixelator.pro b/tests/manual/examples/widgets/itemviews/pixelator/pixelator.pro new file mode 100644 index 0000000000..421f626e28 --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/pixelator.pro @@ -0,0 +1,16 @@ +QT += widgets +requires(qtConfig(tableview)) +qtHaveModule(printsupport): QT += printsupport + +HEADERS = imagemodel.h \ + mainwindow.h \ + pixeldelegate.h +SOURCES = imagemodel.cpp \ + main.cpp \ + mainwindow.cpp \ + pixeldelegate.cpp +RESOURCES += images.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/pixelator +INSTALLS += target diff --git a/tests/manual/examples/widgets/itemviews/pixelator/pixeldelegate.cpp b/tests/manual/examples/widgets/itemviews/pixelator/pixeldelegate.cpp new file mode 100644 index 0000000000..3a104cd2c2 --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/pixeldelegate.cpp @@ -0,0 +1,68 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "pixeldelegate.h" + +#include <QPainter> + +//! [0] +PixelDelegate::PixelDelegate(QObject *parent) + : QAbstractItemDelegate(parent), pixelSize(12) +{} +//! [0] + +//! [1] +void PixelDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ +//! [2] + if (option.state & QStyle::State_Selected) + painter->fillRect(option.rect, option.palette.highlight()); +//! [1] + +//! [3] + const int size = qMin(option.rect.width(), option.rect.height()); +//! [3] //! [4] + const int brightness = index.model()->data(index, Qt::DisplayRole).toInt(); + const double radius = (size / 2.0) - (brightness / 255.0 * size / 2.0); + if (qFuzzyIsNull(radius)) + return; +//! [4] + +//! [5] + painter->save(); +//! [5] //! [6] + painter->setRenderHint(QPainter::Antialiasing, true); +//! [6] //! [7] + painter->setPen(Qt::NoPen); +//! [7] //! [8] + if (option.state & QStyle::State_Selected) +//! [8] //! [9] + painter->setBrush(option.palette.highlightedText()); + else +//! [2] + painter->setBrush(option.palette.text()); +//! [9] + +//! [10] + painter->drawEllipse(QRectF(option.rect.x() + option.rect.width() / 2 - radius, + option.rect.y() + option.rect.height() / 2 - radius, + 2 * radius, 2 * radius)); + painter->restore(); +} +//! [10] + +//! [11] +QSize PixelDelegate::sizeHint(const QStyleOptionViewItem & /* option */, + const QModelIndex & /* index */) const +{ + return QSize(pixelSize, pixelSize); +} +//! [11] + +//! [12] +void PixelDelegate::setPixelSize(int size) +{ + pixelSize = size; +} +//! [12] diff --git a/tests/manual/examples/widgets/itemviews/pixelator/pixeldelegate.h b/tests/manual/examples/widgets/itemviews/pixelator/pixeldelegate.h new file mode 100644 index 0000000000..a4c435ce69 --- /dev/null +++ b/tests/manual/examples/widgets/itemviews/pixelator/pixeldelegate.h @@ -0,0 +1,41 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef PIXELDELEGATE_H +#define PIXELDELEGATE_H + +#include <QAbstractItemDelegate> +#include <QModelIndex> +#include <QSize> + +QT_BEGIN_NAMESPACE +class QAbstractItemModel; +class QObject; +class QPainter; +QT_END_NAMESPACE + +static constexpr int ItemSize = 256; + +//! [0] +class PixelDelegate : public QAbstractItemDelegate +{ + Q_OBJECT + +public: + PixelDelegate(QObject *parent = nullptr); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + +public slots: + void setPixelSize(int size); + +private: + int pixelSize; +}; +//! [0] + +#endif // PIXELDELEGATE_H |