最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt利用QDrag實(shí)現(xiàn)拖拽拼圖功能詳解

 更新時(shí)間:2022年07月25日 08:14:02   作者:wendy_ya  
QDrag類為MIME-based拖拽數(shù)據(jù)轉(zhuǎn)換提供支持。本文為大家主要介紹如何利用QDrag類實(shí)現(xiàn)拖拽拼圖功能。左邊是打散的圖,拖動(dòng)到右邊進(jìn)行復(fù)現(xiàn),此外程序還支持手動(dòng)拖入原圖片,感興趣的可以了解一下

一、項(xiàng)目介紹

本文介紹利用QDrag類實(shí)現(xiàn)拖拽拼圖功能。左邊是打散的圖,拖動(dòng)到右邊進(jìn)行復(fù)現(xiàn),此外程序還支持手動(dòng)拖入原圖片。

二、項(xiàng)目基本配置

新建一個(gè)Qt案例,項(xiàng)目名稱為“puzzle”,基類選擇“QMainWindow”,取消選中創(chuàng)建UI界面復(fù)選框,完成項(xiàng)目創(chuàng)建。

三、UI界面設(shè)置

UI界面如下:

無UI界面

四、主程序?qū)崿F(xiàn)

4.1 main.cpp

源文件main.cpp中需要預(yù)先調(diào)用loadImage函數(shù)加載圖像并顯示界面,代碼如下:

    QApplication a(argc, argv);
    MainWindow w;
    w.loadImage(QStringLiteral(":/example.jpg"));
    w.show();
    return a.exec();

4.1 mainwindow.h頭文件

頭文件中聲明相應(yīng)的對(duì)象和槽函數(shù):

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void loadImage(const QString &path);

public slots:
    void openImage();
    void setupPuzzle();

private slots:
    void setCompleted();

private:
    void setupMenus();
    void setupWidgets();

    QPixmap puzzleImage;
    PiecesList *piecesList;
    PuzzleWidget *puzzleWidget;

4.2 mainwindow.cpp源文件

源文件中對(duì)函數(shù)進(jìn)行定義,首先在構(gòu)造函數(shù)中運(yùn)行setupMenus()函數(shù)和setupWidgets()函數(shù)并設(shè)置大小尺寸和標(biāo)題:

    setupMenus();
    setupWidgets();

    setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));//設(shè)置大小策略
    setWindowTitle(tr("拖拽拼圖"));

定義打開圖像函數(shù):

//打開圖像(重新選擇圖像分割)
void MainWindow::openImage()
{
    const QString directory =
        QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath());
    QFileDialog dialog(this, tr("Open Image"), directory);//創(chuàng)建打開文件對(duì)話框
    dialog.setFileMode(QFileDialog::ExistingFile);//設(shè)置返回存在的文件名
    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());
}

定義加載圖像函數(shù):

// 加載圖片
void MainWindow::loadImage(const QString &fileName)
{
    QPixmap newImage;
    if (!newImage.load(fileName)) {
        QMessageBox::warning(this, tr("Open Image"),
                             tr("The image file could not be loaded."),
                             QMessageBox::Close);
        return;
    }
    puzzleImage = newImage;
    setupPuzzle();
}

拼圖完成后彈出完成對(duì)話框:

//拼圖完成后彈出對(duì)話框
void MainWindow::setCompleted()
{
    QMessageBox::information(this, tr("拼圖完成"),
                             tr("恭喜!您已經(jīng)成功拼圖 \n"
                                "點(diǎn)擊OK重新開始"),
                             QMessageBox::Ok);

    setupPuzzle();
}

建立拼圖函數(shù):

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(),
            puzzleWidget->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//縮放

    piecesList->clear();//清空List
    //切分成5*5=25張拼圖
    for (int y = 0; y < 5; ++y) {
        for (int x = 0; x < 5; ++x) {
            int pieceSize = puzzleWidget->pieceSize();
            QPixmap pieceImage = puzzleImage.copy(x * pieceSize, y * pieceSize, pieceSize, pieceSize);
            piecesList->addPiece(pieceImage, QPoint(x, y));
        }
    }

    for (int i = 0; i < piecesList->count(); ++i) {
        if (QRandomGenerator::global()->bounded(2) == 1) {
            QListWidgetItem *item = piecesList->takeItem(i);
            piecesList->insertItem(0, item);
        }
    }

    puzzleWidget->clear();
}

設(shè)置菜單欄:

//設(shè)置菜單欄
void MainWindow::setupMenus()
{
    QMenu *fileMenu = menuBar()->addMenu(tr("&文件"));

    QAction *openAction = fileMenu->addAction(tr("&打開..."), this, &MainWindow::openImage);
    openAction->setShortcuts(QKeySequence::Open);   //快捷鍵
    QAction *exitAction = fileMenu->addAction(tr("&退出"), qApp, &QCoreApplication::quit);
    exitAction->setShortcuts(QKeySequence::Quit);   //快捷鍵

    QMenu *gameMenu = menuBar()->addMenu(tr("&游戲"));
    gameMenu->addAction(tr("&重啟"), this, &MainWindow::setupPuzzle);
}

設(shè)置界面布局:

//設(shè)置界面布局
void MainWindow::setupWidgets()
{
    QFrame *frame = new QFrame;
    QHBoxLayout *frameLayout = new QHBoxLayout(frame);//水平布局
    puzzleWidget = new PuzzleWidget(400);//新建PuzzleWidget對(duì)象,設(shè)置圖像尺寸為400

    piecesList = new PiecesList(puzzleWidget->pieceSize(), this);


    connect(puzzleWidget, &PuzzleWidget::puzzleCompleted,
            this, &MainWindow::setCompleted, Qt::QueuedConnection);

    frameLayout->addWidget(piecesList);
    frameLayout->addWidget(puzzleWidget);
    setCentralWidget(frame);//中心部件
}

4.3 PiecesList類

新建PiecesList類,并繼承自QListWidget:

4.4 PuzzleWidget類

新建PuzzleWidget類,繼承自QWidget:

它實(shí)現(xiàn)了以下幾個(gè)方法。

    void dragEnterEvent(QDragEnterEvent *event) override;
    void dragLeaveEvent(QDragLeaveEvent *event) override;
    void dragMoveEvent(QDragMoveEvent *event) override;
    void dropEvent(QDropEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void paintEvent(QPaintEvent *event) override;

Drag執(zhí)行的流程是:

Drag是從drag->exec()開始的,此時(shí)將開啟進(jìn)入一個(gè)新的事件循環(huán),然后在拖動(dòng)的過程中會(huì)在下面三個(gè)事件中交替:

其中DragEnter是有拖動(dòng)進(jìn)入該Widget時(shí)觸發(fā)的,對(duì)應(yīng)的DragLeave則是拖動(dòng)離開時(shí)觸發(fā)的,而DragMove就是鼠標(biāo)拖動(dòng)的時(shí)候觸發(fā)的。

最后當(dāng)鼠標(biāo)釋放的時(shí)候?qū)⒂|發(fā)dragEvent,此時(shí)將決定拖拽的結(jié)果。

回頭看一下Drag的觸發(fā),和大多數(shù)系統(tǒng)一樣,一個(gè)Drag可能是從控件外觸發(fā)的,即將外部的數(shù)據(jù)拖入,也可以是從控件內(nèi)部觸發(fā),即手動(dòng)生成一個(gè)QDrag對(duì)象。

拖動(dòng)的機(jī)制:

其實(shí)拖動(dòng)就是將一處的數(shù)據(jù)移動(dòng)或者復(fù)制到另外一處,在QT中拖動(dòng)所承載的數(shù)據(jù)使用QMimeData表示的,它可以用來表示許多Mime Type的集合。一個(gè)Mime Type即有format和data兩部分組成,format即指示了如何解析對(duì)應(yīng)的data。

五、效果演示

完整效果如下:

初始界面:

拼圖完成后界面:

到此這篇關(guān)于Qt利用QDrag實(shí)現(xiàn)拖拽拼圖功能詳解的文章就介紹到這了,更多相關(guān)Qt QDrag拖拽拼圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Easyx實(shí)現(xiàn)掃雷游戲

    Easyx實(shí)現(xiàn)掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了Easyx實(shí)現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++實(shí)現(xiàn)單鏈表按k值重新排序的方法

    C++實(shí)現(xiàn)單鏈表按k值重新排序的方法

    這篇文章主要介紹了C++實(shí)現(xiàn)單鏈表按k值重新排序的方法,結(jié)合實(shí)例形式分析了C++單鏈表中按照給定值進(jìn)行判斷與排序的相關(guān)操作技巧,需要的朋友可以參考下
    2017-05-05
  • C語言實(shí)現(xiàn)萬年歷小程序

    C語言實(shí)現(xiàn)萬年歷小程序

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)萬年歷小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 詳解C語言之函數(shù)

    詳解C語言之函數(shù)

    本文是小結(jié)了一下C語言的函數(shù)語法,詳細(xì)介紹了C語言函數(shù)語法的概述、函數(shù)的定義、函數(shù)的返回值、函數(shù)調(diào)用等7個(gè)方面的內(nèi)容,非常詳細(xì),這里推薦給小伙伴們
    2021-11-11
  • VSCode保存代碼自動(dòng)格式化無效的解決方法

    VSCode保存代碼自動(dòng)格式化無效的解決方法

    最近一直使用vscode,VSCode中各種配置后,自動(dòng)保存格式化仍然無效,本文就來介紹一下解決方法,感興趣的可以了解一下
    2023-08-08
  • C語言常用標(biāo)準(zhǔn)頭文件使用實(shí)例

    C語言常用標(biāo)準(zhǔn)頭文件使用實(shí)例

    在C的系列語言程序中,頭文件(通常擴(kuò)展名為.h)被大量使用,它通常包含函數(shù)、變量、結(jié)構(gòu)體等的聲明和定義,以及一些宏定義和類型定義,這篇文章主要給大家介紹了關(guān)于C語言常用標(biāo)準(zhǔn)頭文件使用的相關(guān)資料,需要的朋友可以參考下
    2024-08-08
  • C語言中自動(dòng)隱式轉(zhuǎn)換與類型強(qiáng)制轉(zhuǎn)換實(shí)例分析

    C語言中自動(dòng)隱式轉(zhuǎn)換與類型強(qiáng)制轉(zhuǎn)換實(shí)例分析

    這篇文章主要介紹了C語言中自動(dòng)隱式轉(zhuǎn)換與類型強(qiáng)制轉(zhuǎn)換實(shí)例分析,需要的朋友可以參考下
    2014-07-07
  • C++與C語言常用的語法對(duì)比

    C++與C語言常用的語法對(duì)比

    這篇文章主要介紹了C++與C語言常用的語法對(duì)比,文章基于c++和C語言的相關(guān)資料展開兩者的語法相互對(duì)比,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助
    2022-04-04
  • Qt之QTimer使用及技巧小結(jié)

    Qt之QTimer使用及技巧小結(jié)

    QTimer是Qt中的定時(shí)器類,用于執(zhí)行定時(shí)操作,如在一段時(shí)間間隔后觸發(fā)某個(gè)槽函數(shù)或執(zhí)行特定的代碼,下面就來介紹一下Qt之QTimer使用及技巧小結(jié),感興趣的可以了解一下
    2023-10-10
  • 用c語言實(shí)現(xiàn)和平精英的完整代碼

    用c語言實(shí)現(xiàn)和平精英的完整代碼

    這篇文章主要介紹了用c語言實(shí)現(xiàn)和平精英的完整代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04

最新評(píng)論

县级市| 三门县| 阿拉善左旗| 娄底市| 玉林市| 平罗县| 丰原市| 广元市| 资阳市| 赣州市| 克山县| 墨竹工卡县| 双牌县| 沅江市| 阜城县| 当涂县| 伊宁县| 龙海市| 乌拉特中旗| 清涧县| 义乌市| 南昌县| 龙江县| 正定县| 大田县| 隆安县| 南充市| 黎川县| 运城市| 济南市| 喀喇沁旗| 济宁市| 重庆市| 上杭县| 贵南县| 赞皇县| 龙山县| 石嘴山市| 乌鲁木齐县| 嘉义市| 寻甸|