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

news/2024/7/23 9:47:32

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();
}

在这里插入图片描述


http://www.niftyadmin.cn/n/1242144.html

相关文章

数据库表名作为参数传递给存储过程的方法

通常的存储过程虽然也可以带参数&#xff0c;但是如果你的存储过程的参数是表名、字段名、数据库名之类的时候&#xff0c;通常的方法就行不通了&#xff01; 下面是用表名做参数的存储过程创建&#xff1a; ?1234567CREATE PROCEDURE SpecialInsertProcedure TableNam…

Day181.Docker网络Springboot打包Docker镜像 -Docker

Docker Docker 网络 理解Docker 0 清空所有网络 # 清空所有容器 docker rm -f $(docker ps -aq) # 清空所有镜像 docker rmi -f $(docker images -aq) 测试 ip addr三个网络 问题&#xff1a; docker 是如果处理容器网络访问的&#xff1f; # 测试 运行一个tomcat [root…

MFC消息映射与命令传递

DECLARE_MESSAGE_MAP宏 在 MFC 几乎每个头文件下&#xff08;类的最后一行声明&#xff09;&#xff0c;都会有这么几行代码&#xff1a; // 生成的消息映射函数 protected: DECLARE_MESSAGE_MAP() 我们看一看 DECLARE_MESSAGE_MAP到底为何物&#xff0c;查看 DECLARE_MESSAGE_…

Qt小例子学习59 - WebEngineView 加载qml显示图表

Qt小例子学习59 - WebEngineView 加载qml显示图表 main.qml import QtQuick 2.9 import QtQuick.Window 2.2 import QtWebEngine 1.5Window {visible: truewidth: 640height: 480title: qsTr("Hello World")WebEngineView {id: webViewanchors.fill: parenturl: &q…

Day182.前言工程搭建[父工程、provider-payment8001、热部署、consumer-order80、工程重构] -SpringCloud.md

SpringCloud 前言 什么是微服务架构&#xff1a; SpringCloud 是微服务一站式服务解决方案&#xff0c;微服务全家桶。它是微服务开发的主流技术栈。它采用了名称&#xff0c;而非数字版本号。 springCloud 和 springCloud Alibaba 目前是最主流的微服务框架组合。 版本选择…

Qt小例子学习60 - pdf 打印表格Qt小例子学习60 - pdf 打印表格

Qt小例子学习60 - pdf 打印表格 connection.h #ifndef CONNECTION_H #define CONNECTION_H#include <QMessageBox> #include <QSqlDatabase> #include <QSqlError> #include <QSqlQuery> static bool createConnection() {QSqlDatabase db QSqlData…

CListCtrl 虚拟列表显示复选框

今天写了个虚拟列表显示复选框的演示程序&#xff0c;放在了&#xff1a;http://download.csdn.net/detail/daiafei/6617913&#xff0c;有不明白的朋友可以下载一下。 在用ClistCtrl控件显示大量数据的时候速度相当慢&#xff0c;而且对内存的占用也是相当大&#xff0c;特别是…

Day182.分布式注册中心[Eureka、Zookeeper、Consul] -SpringCloud

SpringCloud 五、Eureka服务注册与发现 Eureka基础知识 服务治理 服务注册 Eureka两组件 单机Eureka构建步骤 IDEA生成eurekaServer端服务注册中心 1. 建module cloud-eureka-server7001 2. 改pom server端依赖对比&#xff1a; 在pom中添加 <dependencies><…