前言
自己简单实现了下拼图功能.本来开始只是想显示个图片的。
演示图
![请添加图片描述](https://img-blog.csdnimg.cn/c71922e2babf4404bf2805129f13ff76.gif
提示:以下是本篇文章正文内容,下面案例可供参考
1.ShowWidget.h
代码如下(示例):
#ifndef SHOWWIDGET_H
#define SHOWWIDGET_H
#include <QLabel>
#include <QPainter>
#include <QPixmap>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug>
#include <QPaintEvent>
#include <QDrag>
#include <QMimeData>
class ShowWidget : public QWidget
{
Q_OBJECT
public:
ShowWidget(QWidget *parent = nullptr);
~ShowWidget();
void paintEvent(QPaintEvent *paint);
QString getStrIndexFriendly() const;
void setStrIndexFriendly(const QString &value);
void startDrag();
signals:
void sendData(int num1, int num2);
private:
QLabel* m_ImgLab;
QLabel* m_InvertedImgLab;
QVBoxLayout* m_MainLayout;
QString strIndexFriendly;
bool bMouseEnter = false; //记录鼠标是否进入窗口
bool bMousePress = false;
bool bChecked = false; //是否选中
QPoint startPos;
private:
void enterEvent(QEvent *event) Q_DECL_OVERRIDE;
void leaveEvent(QEvent *event) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
};
#endif // SHOWWIDGET_H
2.ShowWidget.cpp
代码如下(示例):
#include "showwidget.h"
#include <QApplication>
ShowWidget::ShowWidget( QWidget *parent)
: QWidget(parent)
{
this->setAcceptDrops(true);
}
ShowWidget::~ShowWidget()
{
}
void ShowWidget::paintEvent(QPaintEvent *paint)
{
Q_UNUSED(paint);
QRect rcBody = rect();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
painter.setPen(Qt::NoPen);
//画一圈红色的外框
if (bMouseEnter || bChecked)
{
painter.setPen(QPen(QColor(255, 0, 0)));
painter.drawRoundRect(rcBody,20,20);
}
//绘制背景
QColor colorBackGround = QColor(155, 155, 155);
if (bMouseEnter || bChecked)
colorBackGround = QColor(180, 180, 180);
painter.setBrush(colorBackGround);
//绘制底图
if (property("background-image").isValid())
{
QImage imageData = property("background-image").value<QImage>();
if (!imageData.isNull())
painter.setBrush(imageData.scaled(rcBody.size()));
}
painter.drawRoundedRect(rcBody, 5, 5);
//绘制文字
QString strIndexFriendly = getStrIndexFriendly();
int nSize = qMin(width(), height());
nSize = qMin(nSize, 18);
if (bMouseEnter || bChecked)
nSize = qMin(nSize+2, 22);
QFont font;
font.setPixelSize(nSize);
painter.setFont(font);
painter.setPen(Qt::white);
if (bMouseEnter || bChecked)
painter.setPen(Qt::black);
painter.drawText(rect(), Qt::AlignCenter, strIndexFriendly);
}
QString ShowWidget::getStrIndexFriendly() const
{
return strIndexFriendly;
}
void ShowWidget::setStrIndexFriendly(const QString &value)
{
strIndexFriendly = value;
}
void ShowWidget::enterEvent(QEvent *event)
{
Q_UNUSED(event);
bMouseEnter = true;
update();
}
void ShowWidget::leaveEvent(QEvent *event)
{
Q_UNUSED(event);
bMouseEnter = false;
update();
}
void ShowWidget::mouseMoveEvent(QMouseEvent *event)
{
if (!acceptDrops())
return;
if (!bMousePress)
return;
if (!(event->buttons() & Qt::LeftButton))
return;
int distance = (event->pos()-startPos).manhattanLength();
if (distance>=QApplication::startDragDistance())
startDrag();
}
void ShowWidget::mousePressEvent(QMouseEvent *event)
{
if (event->button()==Qt::LeftButton)
{
bMousePress = true;
startPos = event->pos();
}
QWidget::mousePressEvent(event);
}
void ShowWidget::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() & Qt::LeftButton)
bMousePress = false;
}
void ShowWidget::startDrag()
{
QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;
mimeData->setText(getStrIndexFriendly());
drag->setMimeData(mimeData);
QPixmap pixmap = this->grab();
if (!pixmap.isNull())
{
//设置缩略图
drag->setPixmap(pixmap);
//设置鼠标在缩略图上的位置
drag->setHotSpot(QPoint(0, pixmap.height()/2));
drag->exec();
}
}
void ShowWidget::dragEnterEvent(QDragEnterEvent *event)
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
void ShowWidget::dragMoveEvent(QDragMoveEvent *event)
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
void ShowWidget::dropEvent(QDropEvent *event)
{
QString str = event->mimeData()->text();
QString arr = getStrIndexFriendly();
emit sendData(str.toInt(),arr.toInt());
event->setDropAction(Qt::MoveAction);
event->accept();
}
3.MainWindow.h
代码如下(示例):
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileDialog>
#include <QGridLayout>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QMessageBox>
#include <QDesktopServices>
#include <QRandomGenerator>
#include "showwidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_lineEdit_2_textEdited(const QString &arg1);
void on_lineEdit_textEdited(const QString &arg1);
void getData(int num1, int num2);
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
private:
Ui::MainWindow *ui;
int xcount = 3, ycount = 4;
QGridLayout *gridLayoutScreenMap; //屏幕窗口表格布局
QList<ShowWidget *> ShowWidgetList;
QList<QImage > myimage;
QMap<int, QImage > imagelist;
QList<int > rnum;
QList<int > correctnum;
QString fileName;
int UsedTime = 0;
int TotleTime = 0;
private:
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);
};
#endif // MAINWINDOW_H
4.MainWindow.cpp
代码如下(示例):
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle("拼图游戏---陈淞(可拖动图片)");
setToolTip("可拖拽图片到窗口添加资源");
gridLayoutScreenMap = new QGridLayout(this);
gridLayoutScreenMap->setContentsMargins(0, 0, 0, 0);
gridLayoutScreenMap->setSpacing(4);
int number = 0;
for (int i = 0; i < xcount; i++)
{
for (int j = 0; j < ycount; j++)
{
number++;
ShowWidget *pSc = new ShowWidget(this);
ShowWidgetList.append(pSc);
connect(pSc,&ShowWidget::sendData,this,&MainWindow::getData);
pSc->setStrIndexFriendly(QString::number(number));
pSc->update();
gridLayoutScreenMap->addWidget(pSc, i, j);
}
}
for (int i = 0; i < xcount*ycount; i++)
{
correctnum.append(i);
}
TotleTime = xcount*ycount+5;
ui->label_3->setText(QString("已用次数: %1").arg(0));
ui->label_5->setText(QString("总共次数: %1").arg(TotleTime));
ui->lineEdit_2->setText(QString::number(xcount));
ui->lineEdit->setText(QString::number(ycount));
ui->pushButton_3->hide();
this->setAcceptDrops(true);
ui->widget->setLayout(gridLayoutScreenMap);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
fileName = QFileDialog::getOpenFileName(this,"选择图片","C:/Users/Administrator/Pictures/","图片文件(*.png *.bmp *.jpg)");
QPixmap pix;
QPixmap pixmap;
pix.load(fileName);
int nycopy = 0,nxcopy = 0,number = 0;
for (int i = 0; i < xcount; i++)
{
for (int j = 0; j < ycount; j++)
{
number++;
pixmap = pix.copy(nxcopy,nycopy,pix.width()/ycount,pix.height()/xcount);
QImage image;
image = pixmap.toImage();
imagelist.insert(number - 1, image);
pixmap.scaled(ShowWidgetList.at(number - 1)->width(),ShowWidgetList.at(number - 1)->height());
ShowWidgetList.at(number - 1)->setProperty("background-image", image);
ShowWidgetList.at(number - 1)->setStrIndexFriendly(QString::number(number));
ShowWidgetList.at(number - 1)->update();
gridLayoutScreenMap->addWidget(ShowWidgetList.at(number - 1), i, j);
nxcopy += pix.width()/ycount;
}
nxcopy = 0;
nycopy += pix.height()/xcount;
}
UsedTime = 0;
TotleTime = xcount*ycount+5;
ui->label_3->setText(QString("已用次数: %1").arg(UsedTime));
ui->label_5->setText(QString("总共次数: %1").arg(TotleTime));
rnum.clear();
while (rnum.count() < xcount*ycount)
{
rnum.append(QRandomGenerator::global()->bounded(xcount*ycount));
rnum.toSet().toList();
for (int i = 0; i < rnum.count(); i++)
{
for (int j = 0; j < rnum.count(); j++)
{
if(rnum.at(i) == rnum.at(j) && (i != j))
rnum.removeAt(i);
}
}
}
for (int i = 0; i < ShowWidgetList.count(); i++)
{
ShowWidgetList.at(i)->setProperty("background-image", imagelist.value(rnum.at(i)));
ShowWidgetList.at(i)->update();
}
}
//拖动进入事件
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
//检查拖放文件的 MIME 类型信息 拖放的是一个 text/uri-list 数据
if (event->mimeData()->hasFormat("text/uri-list"))
{
//我们在事件处理代码中调用 acceptProposeAction()函数,就可以向用户暗示,你可以将拖动的对象放在这个组件上
event->acceptProposedAction();
}
else
{
event->ignore();
}
}
//放下事件
void MainWindow::dropEvent(QDropEvent *event)
{
const QMimeData *mimeData = event->mimeData();
if(mimeData->hasUrls())
{
QList<QUrl>urlList = mimeData->urls();
fileName = urlList.at(0).toLocalFile();
if(!fileName.isEmpty())
{
QPixmap pix;
QPixmap pixmap;
pix.load(fileName);
int nycopy = 0,nxcopy = 0,number = 0;
for (int i = 0; i < xcount; i++)
{
for (int j = 0; j < ycount; j++)
{
number++;
pixmap = pix.copy(nxcopy,nycopy,pix.width()/ycount,pix.height()/xcount);
QImage image;
pixmap.scaled(ShowWidgetList.at(number - 1)->width(),ShowWidgetList.at(number - 1)->height());
image = pixmap.toImage();
imagelist.insert(number - 1, image);
ShowWidgetList.at(number - 1)->setProperty("background-image", image);
ShowWidgetList.at(number - 1)->setStrIndexFriendly(QString::number(number));
ShowWidgetList.at(number - 1)->update();
gridLayoutScreenMap->addWidget(ShowWidgetList.at(number - 1), i, j);
nxcopy += pix.width()/ycount;
}
nxcopy = 0;
nycopy += pix.height()/xcount;
}
}
}
UsedTime = 0;
TotleTime = xcount*ycount+5;
ui->label_3->setText(QString("已用次数: %1").arg(UsedTime));
ui->label_5->setText(QString("总共次数: %1").arg(TotleTime));
rnum.clear();
while (rnum.count() < xcount*ycount)
{
rnum.append(QRandomGenerator::global()->bounded(xcount*ycount));
rnum.toSet().toList();
for (int i = 0; i < rnum.count(); i++)
{
for (int j = 0; j < rnum.count(); j++)
{
if(rnum.at(i) == rnum.at(j) && (i != j))
rnum.removeAt(i);
}
}
}
for (int i = 0; i < ShowWidgetList.count(); i++)
{
ShowWidgetList.at(i)->setProperty("background-image", imagelist.value(rnum.at(i)));
ShowWidgetList.at(i)->update();
}
}
void MainWindow::on_lineEdit_2_textEdited(const QString &arg1)
{
QPixmap pix;
QPixmap pixmap;
pix.load(fileName);
xcount = arg1.toInt();
int nycopy = 0,nxcopy = 0,number = 0;
foreach (auto *pSc, ShowWidgetList)
{
pSc->disconnect();
gridLayoutScreenMap->removeWidget(pSc);
delete pSc;
pSc = nullptr;
}
ShowWidgetList.clear();
for (int i = 0; i < xcount; i++)
{
for (int j = 0; j < ycount; j++)
{
number++;
pixmap = pix.copy(nxcopy,nycopy,pix.width()/ycount,pix.height()/xcount);
ShowWidget *pSc = new ShowWidget(this);
connect(pSc,&ShowWidget::sendData,this,&MainWindow::getData);
pixmap.scaled(pSc->width(),pSc->height());
QImage image;
image = pixmap.toImage();
ShowWidgetList.append(pSc);
imagelist.insert(number - 1, image);
pSc->setProperty("background-image", image);
pSc->setStrIndexFriendly(QString::number(number));
pSc->update();
gridLayoutScreenMap->addWidget(pSc, i, j);
nxcopy += pix.width()/ycount;
}
nxcopy = 0;
nycopy += pix.height()/xcount;
}
UsedTime = 0;
TotleTime = xcount*ycount+5;
ui->label_3->setText(QString("已用次数: %1").arg(UsedTime));
ui->label_5->setText(QString("总共次数: %1").arg(TotleTime));
correctnum.clear();
for (int i = 0; i < xcount*ycount; i++)
{
correctnum.append(i);
}
rnum.clear();
while (rnum.count() < xcount*ycount)
{
rnum.append(QRandomGenerator::global()->bounded(xcount*ycount));
rnum.toSet().toList();
for (int i = 0; i < rnum.count(); i++)
{
for (int j = 0; j < rnum.count(); j++)
{
if(rnum.at(i) == rnum.at(j) && (i != j))
rnum.removeAt(i);
}
}
}
for (int i = 0; i < ShowWidgetList.count(); i++)
{
ShowWidgetList.at(i)->setProperty("background-image", imagelist.value(rnum.at(i)));
ShowWidgetList.at(i)->update();
}
}
void MainWindow::on_lineEdit_textEdited(const QString &arg1)
{
QPixmap pix;
QPixmap pixmap;
pix.load(fileName);
ycount = arg1.toInt();
int nycopy = 0,nxcopy = 0,number = 0;
foreach (auto *pSc, ShowWidgetList)
{
pSc->disconnect();
gridLayoutScreenMap->removeWidget(pSc);
delete pSc;
pSc = nullptr;
}
ShowWidgetList.clear();
for (int i = 0; i < xcount; i++)
{
for (int j = 0; j < ycount; j++)
{
number++;
pixmap = pix.copy(nxcopy,nycopy,pix.width()/ycount,pix.height()/xcount);
ShowWidget *pSc = new ShowWidget(this);
connect(pSc,&ShowWidget::sendData,this,&MainWindow::getData);
pixmap.scaled(pSc->width(),pSc->height());
QImage image;
image = pixmap.toImage();
ShowWidgetList.append(pSc);
imagelist.insert(number - 1, image);
pSc->setProperty("background-image", image);
pSc->setStrIndexFriendly(QString::number(number));
pSc->update();
gridLayoutScreenMap->addWidget(pSc, i, j);
nxcopy += pix.width()/ycount;
}
nxcopy = 0;
nycopy += pix.height()/xcount;
}
UsedTime = 0;
TotleTime = xcount*ycount+5;
ui->label_3->setText(QString("已用次数: %1").arg(UsedTime));
ui->label_5->setText(QString("总共次数: %1").arg(TotleTime));
correctnum.clear();
for (int i = 0; i < xcount*ycount; i++)
{
correctnum.append(i);
}
rnum.clear();
while (rnum.count() < xcount*ycount)
{
rnum.append(QRandomGenerator::global()->bounded(xcount*ycount));
rnum.toSet().toList();
for (int i = 0; i < rnum.count(); i++)
{
for (int j = 0; j < rnum.count(); j++)
{
if(rnum.at(i) == rnum.at(j) && (i != j))
rnum.removeAt(i);
}
}
}
for (int i = 0; i < ShowWidgetList.count(); i++)
{
ShowWidgetList.at(i)->setProperty("background-image", imagelist.value(rnum.at(i)));
ShowWidgetList.at(i)->update();
}
}
void MainWindow::getData(int num1, int num2)
{
qDebug()<< "num1 = " << num1 << "num2 = " << num2;
qDebug()<< "ShowWidgetList.count() = " << ShowWidgetList.count();
QImage image = ShowWidgetList.at(num1 - 1)->property("background-image").value<QImage>();
ShowWidgetList.at(num1 - 1)->setProperty("background-image", ShowWidgetList.at(num2 - 1)->property("background-image").value<QImage>());
ShowWidgetList.at(num2 - 1)->setProperty("background-image",image);
ShowWidgetList.at(num1 - 1)->update();
ShowWidgetList.at(num2 - 1)->update();
UsedTime++;
ui->label_3->setText(QString("已用次数: %1").arg(UsedTime));
rnum.swap(num1 - 1, num2 - 1);
qDebug()<< "rnum = " << rnum << "correctnum = " << correctnum;
if(correctnum == rnum)
{
QMessageBox::information(this,"恭喜","恭喜您成功完成拼图!",QMessageBox::Ok);
UsedTime = 0;
TotleTime = xcount*ycount+5;
ui->label_3->setText(QString("已用次数: %1").arg(UsedTime));
ui->label_5->setText(QString("总共次数: %1").arg(TotleTime));
}
if(TotleTime == UsedTime)
{
QMessageBox::warning(this,"抱歉","很遗憾您未能在规定次数内完成拼图!",QMessageBox::Ok);
UsedTime = 0;
TotleTime = xcount*ycount+5;
ui->label_3->setText(QString("已用次数: %1").arg(UsedTime));
ui->label_5->setText(QString("总共次数: %1").arg(TotleTime));
ui->pushButton_3->show();
}
}
void MainWindow::on_pushButton_2_clicked()
{
QPixmap pix;
QPixmap pixmap;
pix.load(fileName);
int nycopy = 0,nxcopy = 0,number = 0;
for (int i = 0; i < xcount; i++)
{
for (int j = 0; j < ycount; j++)
{
number++;
pixmap = pix.copy(nxcopy,nycopy,pix.width()/ycount,pix.height()/xcount);
QImage image;
image = pixmap.toImage();
imagelist.insert(number - 1, image);
pixmap.scaled(ShowWidgetList.at(number - 1)->width(),ShowWidgetList.at(number - 1)->height());
ShowWidgetList.at(number - 1)->setProperty("background-image", image);
ShowWidgetList.at(number - 1)->setStrIndexFriendly(QString::number(number));
ShowWidgetList.at(number - 1)->update();
gridLayoutScreenMap->addWidget(ShowWidgetList.at(number - 1), i, j);
nxcopy += pix.width()/ycount;
}
nxcopy = 0;
nycopy += pix.height()/xcount;
}
UsedTime = 0;
TotleTime = xcount*ycount+5;
ui->label_3->setText(QString("已用次数: %1").arg(UsedTime));
ui->label_5->setText(QString("总共次数: %1").arg(TotleTime));
rnum.clear();
while (rnum.count() < xcount*ycount)
{
rnum.append(QRandomGenerator::global()->bounded(xcount*ycount));
rnum.toSet().toList();
for (int i = 0; i < rnum.count(); i++)
{
for (int j = 0; j < rnum.count(); j++)
{
if(rnum.at(i) == rnum.at(j) && (i != j))
rnum.removeAt(i);
}
}
}
for (int i = 0; i < ShowWidgetList.count(); i++)
{
ShowWidgetList.at(i)->setProperty("background-image", imagelist.value(rnum.at(i)));
ShowWidgetList.at(i)->update();
}
}
void MainWindow::on_pushButton_3_clicked()
{
for (int i = 0; i < ShowWidgetList.count(); i++)
{
ShowWidgetList.at(i)->setProperty("background-image", imagelist.value(i));
ShowWidgetList.at(i)->update();
}
ui->pushButton_3->hide();
}
文章来源:https://www.toymoban.com/news/detail-518988.html
源码下载文章来源地址https://www.toymoban.com/news/detail-518988.html
到了这里,关于Qt实现简单拼图游戏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!