Qt小例子学习58 - 向QGraphicsScene 添加 pixmaps

Qt小例子学习58 - 向QGraphicsScene 添加 pixmaps

Block.h

#ifndef BLOCK_H
#define BLOCK_H

#include <QGraphicsPathItem>
class QGraphicsSceneMouseEvent;
class Block : public QGraphicsPathItem
{
public:
    enum { Type = QGraphicsItem::UserType + 3 };
    int type() const { return Type; }
    Block(QGraphicsItem *parent = 0);
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
               QWidget *widget);
};

#endif // BLOCK_H

Block.cpp

#include "block.h"

#include <QPainter>

class QGraphicsSceneMouseEvent;
Block::Block(QGraphicsItem *parent) : QGraphicsPathItem(parent)
{
    QPainterPath p;
    //<->,|,<->,|,roundness
    p.addRoundedRect(0, 0, 80, 50, 5, 5);
    setPath(p);
    setAcceptDrops(true);
    setAcceptedMouseButtons(Qt::LeftButton);
}
void Block::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                  QWidget *widget)
{
    Q_UNUSED(option)
    Q_UNUSED(widget)
    painter->setPen(QPen(QColor(67, 141, 220)));
    painter->setBrush(QColor(67, 141, 220, 100));
    painter->drawPath(path());
}

GraphicsScene.h

#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H

#include <QGraphicsScene>

class QMenu;
class QAction;

class GraphicsScene : public QGraphicsScene
{
public:
    using QGraphicsScene::QGraphicsScene;

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    void dropEvent(QGraphicsSceneDragDropEvent *event) override;

private:
    QGraphicsPixmapItem *findPixmapItem(QGraphicsItem *item);
    void createDrag(const QPointF &pos, QWidget *widget, QGraphicsItem *item);
    void showContextMenu(const QPointF &pos);
    void addPixBlock(QGraphicsItem *item);

    QMenu *menu;
    QMenu *submenu;
    QAction *picture;
    QGraphicsPixmapItem *pix;
};

#endif // GRAPHICSSCENE_H

GraphicsScene.cpp

#include "graphicsscene.h"

#include <QDrag>
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QMenu>
#include <QMimeData>
#include <QWidget>

void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    auto its = items(QRectF(event->scenePos() - QPointF(1, 1), QSize(3, 3)));
    auto val = std::find_if(its.constBegin(), its.constEnd(), [](auto const & it)
    {
        return it->type() > QGraphicsItem::UserType;
    });
    if (val == its.constEnd())
        return;
    if (event->button() == Qt::RightButton)
    {
        showContextMenu(event->scenePos());
    }
    else
    {
        createDrag(event->scenePos(), event->widget(), *val);
    }
}

void GraphicsScene::dropEvent(QGraphicsSceneDragDropEvent *event)
{
    QByteArray byteArray = event->mimeData()->data("Item");
    QGraphicsPixmapItem *item =
        *reinterpret_cast<QGraphicsPixmapItem **>(byteArray.data());
    QGraphicsItem *item_parent = itemAt(event->scenePos(), QTransform());
    item->setParentItem(item_parent);
}

QGraphicsPixmapItem *GraphicsScene::findPixmapItem(QGraphicsItem *item)
{
    auto chs = item->childItems();
    auto val = std::find_if(chs.constBegin(), chs.constEnd(), [](auto const & it)
    {
        return static_cast<QGraphicsPixmapItem *>(it) != Q_NULLPTR;
    });
    return val == chs.constEnd() ? Q_NULLPTR
           : static_cast<QGraphicsPixmapItem *>(*val);
}

void GraphicsScene::createDrag(const QPointF &pos, QWidget *widget,
                               QGraphicsItem *item)
{
    QGraphicsPixmapItem *pix = findPixmapItem(item);
    if (pix == Q_NULLPTR)
        return;
    QByteArray byteArray(reinterpret_cast<char *>(&pix),
                         sizeof(QGraphicsPixmapItem *));
    QDrag *drag = new QDrag(widget);
    QMimeData *mimeData = new QMimeData;
    mimeData->setData("Item", byteArray);
    drag->setMimeData(mimeData);
    drag->setHotSpot(pos.toPoint() - pix->scenePos().toPoint());
    drag->setPixmap(pix->pixmap());
    drag->start();
}

void GraphicsScene::showContextMenu(const QPointF &pos)
{
    QGraphicsItem *item = itemAt(pos, QTransform());
    menu = new QMenu("Menu");
    submenu = menu->addMenu(QIcon(":/img/pix.png"), "Pix");
    picture = submenu->addAction(QIcon(":/img/pix.png"), "Pix");
    connect(picture, &QAction::triggered, [item, this]() { addPixBlock(item); });
    menu->exec(QCursor::pos());
}

void GraphicsScene::addPixBlock(QGraphicsItem *item)
{
    if (findPixmapItem(item))
        return;
    QPixmap pixmap(":/img/pix.png");
    pix = addPixmap(pixmap.scaled(70, 50));
    if (pix->parentItem() != item)
        pix->setParentItem(item);
}

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class GraphicsScene;
class QGraphicsItem;
class QGraphicsPixmapItem;

namespace Ui
{
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    GraphicsScene *scene;
};

#endif // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"
#include "block.h"
#include "ui_mainwindow.h"

#include "graphicsscene.h"

#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    scene = new GraphicsScene;
    ui->graphicsView->setScene(scene);
    for (int row = -4; row < 8; ++row)
        for (int column = 0; column < 4; ++column)
        {
            Block *b = new Block;
            scene->addItem(b);
            b->setPos(row * 95, column * 85);
        }
}
MainWindow::~MainWindow() { delete ui; }

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值