Revamp QtWidgets/DragAndDrop examples to C++11

Introduce nullptr and replace foreach with new C++11 range based for
loops. Minor fixups of signals, file dialog usage.

Apply the same changes to the ItemViews/puzzle example since it
shares parts of the code with DragAndDrop/puzzle. Make some
changes to both examples to that the diff of the two becomes
small for easier comparison.

Task-number: QTBUG-60635
Change-Id: I8af824229ebac24d6ec151eae92176d227695490
Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
This commit is contained in:
Friedemann Kleint 2017-08-24 11:19:21 +02:00
parent 3fe74b76fd
commit 879f98106d
19 changed files with 125 additions and 122 deletions

View File

@ -62,7 +62,7 @@ QT_END_NAMESPACE
class DragWidget : public QFrame
{
public:
DragWidget(QWidget *parent = 0);
explicit DragWidget(QWidget *parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;

View File

@ -123,7 +123,7 @@ void DragWidget::dropEvent(QDropEvent *event)
hotSpot.setY(hotSpotPos.last().toInt());
}
foreach (const QString &piece, pieces) {
for (const QString &piece : pieces) {
QLabel *newLabel = createDragLabel(piece, this);
newLabel->move(position - hotSpot);
newLabel->show();
@ -141,7 +141,7 @@ void DragWidget::dropEvent(QDropEvent *event)
} else {
event->ignore();
}
foreach (QWidget *widget, findChildren<QWidget *>()) {
for (QWidget *widget : findChildren<QWidget *>()) {
if (!widget->isVisible())
widget->deleteLater();
}

View File

@ -61,7 +61,7 @@ QT_END_NAMESPACE
class DragWidget : public QWidget
{
public:
DragWidget(QWidget *parent = 0);
explicit DragWidget(QWidget *parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;

View File

@ -63,13 +63,13 @@ class DropArea : public QLabel
Q_OBJECT
public:
DropArea(QWidget *parent = 0);
explicit DropArea(QWidget *parent = nullptr);
public slots:
void clear();
signals:
void changed(const QMimeData *mimeData = 0);
void changed(const QMimeData *mimeData = nullptr);
//! [DropArea header part1]
//! [DropArea header part2]

View File

@ -88,8 +88,8 @@ DropSiteWindow::DropSiteWindow()
buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
connect(quitButton, &QAbstractButton::pressed, this, &QWidget::close);
connect(clearButton, &QAbstractButton::pressed, dropArea, &DropArea::clear);
connect(quitButton, &QAbstractButton::clicked, this, &QWidget::close);
connect(clearButton, &QAbstractButton::clicked, dropArea, &DropArea::clear);
//! [constructor part4]
//! [constructor part5]
@ -113,7 +113,7 @@ void DropSiteWindow::updateFormatsTable(const QMimeData *mimeData)
//! [updateFormatsTable() part1]
//! [updateFormatsTable() part2]
foreach (QString format, mimeData->formats()) {
for (const QString &format : mimeData->formats()) {
QTableWidgetItem *formatItem = new QTableWidgetItem(format);
formatItem->setFlags(Qt::ItemIsEnabled);
formatItem->setTextAlignment(Qt::AlignTop | Qt::AlignLeft);

View File

@ -167,7 +167,7 @@ void DragWidget::dropEvent(QDropEvent *event)
QString::SkipEmptyParts);
QPoint position = event->pos();
foreach (const QString &piece, pieces) {
for (const QString &piece : pieces) {
DragLabel *newLabel = new DragLabel(piece, this);
newLabel->move(position);
newLabel->show();

View File

@ -62,7 +62,7 @@ QT_END_NAMESPACE
class DragWidget : public QWidget
{
public:
DragWidget(QWidget *parent = 0);
explicit DragWidget(QWidget *parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;

View File

@ -48,10 +48,10 @@
**
****************************************************************************/
#include <QApplication>
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(puzzle);

View File

@ -67,12 +67,19 @@ MainWindow::MainWindow(QWidget *parent)
void MainWindow::openImage()
{
const QString fileName =
QFileDialog::getOpenFileName(this, tr("Open Image"), QString(),
tr("Image Files (*.png *.jpg *.bmp)"));
if (!fileName.isEmpty())
loadImage(fileName);
const QString directory =
QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath());
QFileDialog dialog(this, tr("Open Image"), directory);
dialog.setAcceptMode(QFileDialog::AcceptOpen);
dialog.setFileMode(QFileDialog::ExistingFile);
QStringList mimeTypeFilters;
for (const QByteArray &mimeTypeName : QImageReader::supportedMimeTypes())
mimeTypeFilters.append(mimeTypeName);
mimeTypeFilters.sort();
dialog.setMimeTypeFilters(mimeTypeFilters);
dialog.selectMimeTypeFilter("image/jpeg");
if (dialog.exec() == QDialog::Accepted)
loadImage(dialog.selectedFiles().constFirst());
}
void MainWindow::loadImage(const QString &fileName)
@ -101,8 +108,8 @@ void MainWindow::setCompleted()
void MainWindow::setupPuzzle()
{
int size = qMin(puzzleImage.width(), puzzleImage.height());
puzzleImage = puzzleImage.copy((puzzleImage.width() - size)/2,
(puzzleImage.height() - size)/2, size, size).scaled(puzzleWidget->width(),
puzzleImage = puzzleImage.copy((puzzleImage.width() - size) / 2,
(puzzleImage.height() - size) / 2, size, size).scaled(puzzleWidget->width(),
puzzleWidget->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
piecesList->clear();

View File

@ -51,8 +51,8 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QPixmap>
#include <QMainWindow>
#include <QPixmap>
class PiecesList;
class PuzzleWidget;
@ -65,7 +65,7 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
explicit MainWindow(QWidget *parent = nullptr);
void loadImage(const QString &path);
public slots:

View File

@ -101,7 +101,7 @@ void PiecesList::dropEvent(QDropEvent *event)
}
}
void PiecesList::addPiece(QPixmap pixmap, QPoint location)
void PiecesList::addPiece(const QPixmap &pixmap, const QPoint &location)
{
QListWidgetItem *pieceItem = new QListWidgetItem(this);
pieceItem->setIcon(QIcon(pixmap));

View File

@ -58,8 +58,8 @@ class PiecesList : public QListWidget
Q_OBJECT
public:
explicit PiecesList(int pieceSize, QWidget *parent = 0);
void addPiece(QPixmap pixmap, QPoint location);
explicit PiecesList(int pieceSize, QWidget *parent = nullptr);
void addPiece(const QPixmap &pixmap, const QPoint &location);
static QString puzzleMimeType() { return QStringLiteral("image/x-puzzle-piece"); }

View File

@ -66,9 +66,7 @@ PuzzleWidget::PuzzleWidget(int imageSize, QWidget *parent)
void PuzzleWidget::clear()
{
pieceLocations.clear();
piecePixmaps.clear();
pieceRects.clear();
pieces.clear();
highlightedRect = QRect();
inPlace = 0;
update();
@ -95,7 +93,7 @@ void PuzzleWidget::dragMoveEvent(QDragMoveEvent *event)
QRect updateRect = highlightedRect.united(targetSquare(event->pos()));
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
&& pieceRects.indexOf(targetSquare(event->pos())) == -1) {
&& findPiece(targetSquare(event->pos())) == -1) {
highlightedRect = targetSquare(event->pos());
event->setDropAction(Qt::MoveAction);
@ -111,26 +109,23 @@ void PuzzleWidget::dragMoveEvent(QDragMoveEvent *event)
void PuzzleWidget::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
&& pieceRects.indexOf(targetSquare(event->pos())) == -1) {
&& findPiece(targetSquare(event->pos())) == -1) {
QByteArray pieceData = event->mimeData()->data(PiecesList::puzzleMimeType());
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
QRect square = targetSquare(event->pos());
QPixmap pixmap;
QPoint location;
dataStream >> pixmap >> location;
Piece piece;
piece.rect = targetSquare(event->pos());
dataStream >> piece.pixmap >> piece.location;
pieceLocations.append(location);
piecePixmaps.append(pixmap);
pieceRects.append(square);
pieces.append(piece);
highlightedRect = QRect();
update(square);
update(piece.rect);
event->setDropAction(Qt::MoveAction);
event->accept();
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) {
if (piece.location == piece.rect.topLeft() / pieceSize()) {
inPlace++;
if (inPlace == 25)
emit puzzleCompleted();
@ -141,21 +136,26 @@ void PuzzleWidget::dropEvent(QDropEvent *event)
}
}
int PuzzleWidget::findPiece(const QRect &pieceRect) const
{
for (int i = 0, size = pieces.size(); i < size; ++i) {
if (pieces.at(i).rect == pieceRect)
return i;
}
return -1;
}
void PuzzleWidget::mousePressEvent(QMouseEvent *event)
{
QRect square = targetSquare(event->pos());
int found = pieceRects.indexOf(square);
const int found = findPiece(square);
if (found == -1)
return;
QPoint location = pieceLocations[found];
QPixmap pixmap = piecePixmaps[found];
pieceLocations.removeAt(found);
piecePixmaps.removeAt(found);
pieceRects.removeAt(found);
Piece piece = pieces.takeAt(found);
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
if (piece.location == square.topLeft() / pieceSize())
inPlace--;
update(square);
@ -163,7 +163,7 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << pixmap << location;
dataStream << piece.pixmap << piece.location;
QMimeData *mimeData = new QMimeData;
mimeData->setData(PiecesList::puzzleMimeType(), itemData);
@ -171,23 +171,20 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setHotSpot(event->pos() - square.topLeft());
drag->setPixmap(pixmap);
drag->setPixmap(piece.pixmap);
if (!(drag->exec(Qt::MoveAction) == Qt::MoveAction)) {
pieceLocations.insert(found, location);
piecePixmaps.insert(found, pixmap);
pieceRects.insert(found, square);
if (drag->exec(Qt::MoveAction) != Qt::MoveAction) {
pieces.insert(found, piece);
update(targetSquare(event->pos()));
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
if (piece.location == square.topLeft() / pieceSize())
inPlace++;
}
}
void PuzzleWidget::paintEvent(QPaintEvent *event)
{
QPainter painter;
painter.begin(this);
QPainter painter(this);
painter.fillRect(event->rect(), Qt::white);
if (highlightedRect.isValid()) {
@ -196,14 +193,14 @@ void PuzzleWidget::paintEvent(QPaintEvent *event)
painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1));
}
for (int i = 0; i < pieceRects.size(); ++i)
painter.drawPixmap(pieceRects[i], piecePixmaps[i]);
painter.end();
for (const Piece &piece : pieces)
painter.drawPixmap(piece.rect, piece.pixmap);
}
const QRect PuzzleWidget::targetSquare(const QPoint &position) const
{
return QRect(position.x()/pieceSize() * pieceSize(), position.y()/pieceSize() * pieceSize(), pieceSize(), pieceSize());
return QRect(position / pieceSize() * pieceSize(),
QSize(pieceSize(), pieceSize()));
}
int PuzzleWidget::pieceSize() const

View File

@ -51,9 +51,9 @@
#ifndef PUZZLEWIDGET_H
#define PUZZLEWIDGET_H
#include <QList>
#include <QPoint>
#include <QPixmap>
#include <QVector>
#include <QWidget>
QT_BEGIN_NAMESPACE
@ -67,7 +67,7 @@ class PuzzleWidget : public QWidget
Q_OBJECT
public:
explicit PuzzleWidget(int imageSize, QWidget *parent = 0);
explicit PuzzleWidget(int imageSize, QWidget *parent = nullptr);
void clear();
int pieceSize() const;
@ -85,11 +85,16 @@ protected:
void paintEvent(QPaintEvent *event) override;
private:
struct Piece {
QPixmap pixmap;
QRect rect;
QPoint location;
};
int findPiece(const QRect &pieceRect) const;
const QRect targetSquare(const QPoint &position) const;
QList<QPixmap> piecePixmaps;
QList<QRect> pieceRects;
QList<QPoint> pieceLocations;
QVector<Piece> pieces;
QRect highlightedRect;
int inPlace;
int m_ImageSize;

View File

@ -58,7 +58,7 @@ int main(int argc, char *argv[])
QApplication app(argc, argv);
MainWindow window;
window.loadImage(":/images/example.jpg");
window.loadImage(QStringLiteral(":/images/example.jpg"));
window.show();
return app.exec();
}

View File

@ -69,12 +69,19 @@ MainWindow::MainWindow(QWidget *parent)
void MainWindow::openImage()
{
const QString fileName =
QFileDialog::getOpenFileName(this,
tr("Open Image"), QString(),
tr("Image Files (*.png *.jpg *.bmp)"));
if (!fileName.isEmpty())
loadImage(fileName);
const QString directory =
QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath());
QFileDialog dialog(this, tr("Open Image"), directory);
dialog.setAcceptMode(QFileDialog::AcceptOpen);
dialog.setFileMode(QFileDialog::ExistingFile);
QStringList mimeTypeFilters;
for (const QByteArray &mimeTypeName : QImageReader::supportedMimeTypes())
mimeTypeFilters.append(mimeTypeName);
mimeTypeFilters.sort();
dialog.setMimeTypeFilters(mimeTypeFilters);
dialog.selectMimeTypeFilter("image/jpeg");
if (dialog.exec() == QDialog::Accepted)
loadImage(dialog.selectedFiles().constFirst());
}
void MainWindow::loadImage(const QString &fileName)
@ -83,7 +90,7 @@ void MainWindow::loadImage(const QString &fileName)
if (!newImage.load(fileName)) {
QMessageBox::warning(this, tr("Open Image"),
tr("The image file could not be loaded."),
QMessageBox::Cancel);
QMessageBox::Close);
return;
}
puzzleImage = newImage;
@ -117,19 +124,15 @@ void MainWindow::setupMenus()
{
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
QAction *openAction = fileMenu->addAction(tr("&Open..."));
QAction *openAction = fileMenu->addAction(tr("&Open..."), this, &MainWindow::openImage);
openAction->setShortcuts(QKeySequence::Open);
QAction *exitAction = fileMenu->addAction(tr("E&xit"));
QAction *exitAction = fileMenu->addAction(tr("E&xit"), qApp, &QCoreApplication::quit);
exitAction->setShortcuts(QKeySequence::Quit);
QMenu *gameMenu = menuBar()->addMenu(tr("&Game"));
QAction *restartAction = gameMenu->addAction(tr("&Restart"));
connect(openAction, &QAction::triggered, this, &MainWindow::openImage);
connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
connect(restartAction, &QAction::triggered, this, &MainWindow::setupPuzzle);
gameMenu->addAction(tr("&Restart"), this, &MainWindow::setupPuzzle);
}
void MainWindow::setupWidgets()

View File

@ -65,7 +65,7 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
explicit MainWindow(QWidget *parent = nullptr);
public slots:
void openImage();

View File

@ -62,9 +62,7 @@ PuzzleWidget::PuzzleWidget(int imageSize, QWidget *parent)
void PuzzleWidget::clear()
{
pieceLocations.clear();
piecePixmaps.clear();
pieceRects.clear();
pieces.clear();
highlightedRect = QRect();
inPlace = 0;
update();
@ -110,23 +108,20 @@ void PuzzleWidget::dropEvent(QDropEvent *event)
&& findPiece(targetSquare(event->pos())) == -1) {
QByteArray pieceData = event->mimeData()->data("image/x-puzzle-piece");
QDataStream stream(&pieceData, QIODevice::ReadOnly);
QRect square = targetSquare(event->pos());
QPixmap pixmap;
QPoint location;
stream >> pixmap >> location;
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
Piece piece;
piece.rect = targetSquare(event->pos());
dataStream >> piece.pixmap >> piece.location;
pieceLocations.append(location);
piecePixmaps.append(pixmap);
pieceRects.append(square);
pieces.append(piece);
highlightedRect = QRect();
update(square);
update(piece.rect);
event->setDropAction(Qt::MoveAction);
event->accept();
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) {
if (piece.location == piece.rect.topLeft() / pieceSize()) {
inPlace++;
if (inPlace == 25)
emit puzzleCompleted();
@ -139,8 +134,8 @@ void PuzzleWidget::dropEvent(QDropEvent *event)
int PuzzleWidget::findPiece(const QRect &pieceRect) const
{
for (int i = 0; i < pieceRects.size(); ++i) {
if (pieceRect == pieceRects[i])
for (int i = 0, size = pieces.size(); i < size; ++i) {
if (pieces.at(i).rect == pieceRect)
return i;
}
return -1;
@ -154,13 +149,9 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
if (found == -1)
return;
QPoint location = pieceLocations[found];
QPixmap pixmap = piecePixmaps[found];
pieceLocations.removeAt(found);
piecePixmaps.removeAt(found);
pieceRects.removeAt(found);
Piece piece = pieces.takeAt(found);
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
if (piece.location == square.topLeft() / pieceSize())
inPlace--;
update(square);
@ -168,7 +159,7 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << pixmap << location;
dataStream << piece.pixmap << piece.location;
QMimeData *mimeData = new QMimeData;
mimeData->setData("image/x-puzzle-piece", itemData);
@ -176,23 +167,20 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setHotSpot(event->pos() - square.topLeft());
drag->setPixmap(pixmap);
drag->setPixmap(piece.pixmap);
if (drag->start(Qt::MoveAction) == 0) {
pieceLocations.insert(found, location);
piecePixmaps.insert(found, pixmap);
pieceRects.insert(found, square);
if (drag->start(Qt::MoveAction) == Qt::IgnoreAction) {
pieces.insert(found, piece);
update(targetSquare(event->pos()));
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
if (piece.location == QPoint(square.x() / pieceSize(), square.y() / pieceSize()))
inPlace++;
}
}
void PuzzleWidget::paintEvent(QPaintEvent *event)
{
QPainter painter;
painter.begin(this);
QPainter painter(this);
painter.fillRect(event->rect(), Qt::white);
if (highlightedRect.isValid()) {
@ -201,15 +189,14 @@ void PuzzleWidget::paintEvent(QPaintEvent *event)
painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1));
}
for (int i = 0; i < pieceRects.size(); ++i) {
painter.drawPixmap(pieceRects[i], piecePixmaps[i]);
}
painter.end();
for (const Piece &piece : pieces)
painter.drawPixmap(piece.rect, piece.pixmap);
}
const QRect PuzzleWidget::targetSquare(const QPoint &position) const
{
return QRect(position.x()/pieceSize() * pieceSize(), position.y()/pieceSize() * pieceSize(), pieceSize(), pieceSize());
return QRect(position / pieceSize() * pieceSize(),
QSize(pieceSize(), pieceSize()));
}
int PuzzleWidget::pieceSize() const

View File

@ -51,9 +51,9 @@
#ifndef PUZZLEWIDGET_H
#define PUZZLEWIDGET_H
#include <QList>
#include <QPixmap>
#include <QPoint>
#include <QPixmap>
#include <QVector>
#include <QWidget>
QT_BEGIN_NAMESPACE
@ -67,7 +67,7 @@ class PuzzleWidget : public QWidget
Q_OBJECT
public:
explicit PuzzleWidget(int imageSize, QWidget *parent = 0);
explicit PuzzleWidget(int imageSize, QWidget *parent = nullptr);
void clear();
int pieceSize() const;
@ -85,12 +85,16 @@ protected:
void paintEvent(QPaintEvent *event) override;
private:
struct Piece {
QPixmap pixmap;
QRect rect;
QPoint location;
};
int findPiece(const QRect &pieceRect) const;
const QRect targetSquare(const QPoint &position) const;
QList<QPixmap> piecePixmaps;
QList<QRect> pieceRects;
QList<QPoint> pieceLocations;
QVector<Piece> pieces;
QRect highlightedRect;
int inPlace;
int m_ImageSize;