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 class DragWidget : public QFrame
{ {
public: public:
DragWidget(QWidget *parent = 0); explicit DragWidget(QWidget *parent = nullptr);
protected: protected:
void dragEnterEvent(QDragEnterEvent *event) override; void dragEnterEvent(QDragEnterEvent *event) override;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -67,12 +67,19 @@ MainWindow::MainWindow(QWidget *parent)
void MainWindow::openImage() void MainWindow::openImage()
{ {
const QString fileName = const QString directory =
QFileDialog::getOpenFileName(this, tr("Open Image"), QString(), QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath());
tr("Image Files (*.png *.jpg *.bmp)")); QFileDialog dialog(this, tr("Open Image"), directory);
dialog.setAcceptMode(QFileDialog::AcceptOpen);
if (!fileName.isEmpty()) dialog.setFileMode(QFileDialog::ExistingFile);
loadImage(fileName); 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) void MainWindow::loadImage(const QString &fileName)

View File

@ -51,8 +51,8 @@
#ifndef MAINWINDOW_H #ifndef MAINWINDOW_H
#define MAINWINDOW_H #define MAINWINDOW_H
#include <QPixmap>
#include <QMainWindow> #include <QMainWindow>
#include <QPixmap>
class PiecesList; class PiecesList;
class PuzzleWidget; class PuzzleWidget;
@ -65,7 +65,7 @@ class MainWindow : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
MainWindow(QWidget *parent = 0); explicit MainWindow(QWidget *parent = nullptr);
void loadImage(const QString &path); void loadImage(const QString &path);
public slots: 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); QListWidgetItem *pieceItem = new QListWidgetItem(this);
pieceItem->setIcon(QIcon(pixmap)); pieceItem->setIcon(QIcon(pixmap));

View File

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

View File

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

View File

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

View File

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

View File

@ -69,12 +69,19 @@ MainWindow::MainWindow(QWidget *parent)
void MainWindow::openImage() void MainWindow::openImage()
{ {
const QString fileName = const QString directory =
QFileDialog::getOpenFileName(this, QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath());
tr("Open Image"), QString(), QFileDialog dialog(this, tr("Open Image"), directory);
tr("Image Files (*.png *.jpg *.bmp)")); dialog.setAcceptMode(QFileDialog::AcceptOpen);
if (!fileName.isEmpty()) dialog.setFileMode(QFileDialog::ExistingFile);
loadImage(fileName); 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) void MainWindow::loadImage(const QString &fileName)
@ -83,7 +90,7 @@ void MainWindow::loadImage(const QString &fileName)
if (!newImage.load(fileName)) { if (!newImage.load(fileName)) {
QMessageBox::warning(this, tr("Open Image"), QMessageBox::warning(this, tr("Open Image"),
tr("The image file could not be loaded."), tr("The image file could not be loaded."),
QMessageBox::Cancel); QMessageBox::Close);
return; return;
} }
puzzleImage = newImage; puzzleImage = newImage;
@ -117,19 +124,15 @@ void MainWindow::setupMenus()
{ {
QMenu *fileMenu = menuBar()->addMenu(tr("&File")); 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); 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); exitAction->setShortcuts(QKeySequence::Quit);
QMenu *gameMenu = menuBar()->addMenu(tr("&Game")); QMenu *gameMenu = menuBar()->addMenu(tr("&Game"));
QAction *restartAction = gameMenu->addAction(tr("&Restart")); gameMenu->addAction(tr("&Restart"), this, &MainWindow::setupPuzzle);
connect(openAction, &QAction::triggered, this, &MainWindow::openImage);
connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
connect(restartAction, &QAction::triggered, this, &MainWindow::setupPuzzle);
} }
void MainWindow::setupWidgets() void MainWindow::setupWidgets()

View File

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

View File

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

View File

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