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:
parent
3fe74b76fd
commit
879f98106d
@ -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;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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]
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
@ -101,8 +108,8 @@ void MainWindow::setCompleted()
|
|||||||
void MainWindow::setupPuzzle()
|
void MainWindow::setupPuzzle()
|
||||||
{
|
{
|
||||||
int size = qMin(puzzleImage.width(), puzzleImage.height());
|
int size = qMin(puzzleImage.width(), puzzleImage.height());
|
||||||
puzzleImage = puzzleImage.copy((puzzleImage.width() - size)/2,
|
puzzleImage = puzzleImage.copy((puzzleImage.width() - size) / 2,
|
||||||
(puzzleImage.height() - size)/2, size, size).scaled(puzzleWidget->width(),
|
(puzzleImage.height() - size) / 2, size, size).scaled(puzzleWidget->width(),
|
||||||
puzzleWidget->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
puzzleWidget->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
|
||||||
piecesList->clear();
|
piecesList->clear();
|
||||||
|
@ -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:
|
||||||
|
@ -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));
|
||||||
|
@ -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"); }
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user