QGraphicsView进阶篇

1、缩放与旋转

QGraphicsView 通过 QGraphicsView::setMatrix() 支持和 QPainter 一样的仿射变换,通过对一个视图应用变换,你可以很容易地支持普通的导航特性如缩放与旋转。
代码示例如下:
CustomView.h如下:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_CustomView.h"
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QVBoxLayout>
#include <QPushButton>


class CustomView : public QGraphicsView
{
    Q_OBJECT
public:
    CustomView(QWidget *parent = nullptr);
    ~CustomView();
public slots:
    void zoomIn();
    void zoomOut();
    void rotateLeft();
    void rotateRight();

private:
    Ui::CustomViewClass ui;
};

CustomView.cpp如下:

#include "CustomView.h"

CustomView::CustomView(QWidget *parent)
    : QGraphicsView(parent)
{
    //ui.setupUi(this);
}

CustomView::~CustomView()
{}

void CustomView::zoomOut()
{
    this->scale(1/1.2,1/.2);
}

void CustomView::rotateLeft()
{
    this->rotate(-90);
}

void CustomView::rotateRight()
{
    this->rotate(90);
}

void CustomView::zoomIn()
{
    this->scale(1.2, 1.2);
}

main.cpp如下:

#include "CustomView.h"
#include <QtWidgets/QApplication>
#include<qpushbutton.h>
#include<qwidget.h>
#include<QVBoxLayout>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene;
    scene.setBackgroundBrush(Qt::red);
    QPen pen;
    pen.setWidth(6);
    pen.setBrush(Qt::blue);
    QGraphicsRectItem* rect = new QGraphicsRectItem();
    rect->setPen(pen);
    rect->setRect(QRectF(100, 100, 200, 200));
    rect->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable);
    scene.addItem(rect);
    QPushButton* zoomIn = new QPushButton("zoomIn");
    QPushButton* zoomOut = new QPushButton("zoomOut");
    QPushButton* rotateLeft = new QPushButton("rotateLeft");
    QPushButton* rotateRight = new QPushButton("rotateRight");
    QVBoxLayout* mainLayout = new QVBoxLayout();
    mainLayout->addWidget(zoomIn);
    mainLayout->addWidget(zoomOut);
    mainLayout->addWidget(rotateLeft);
    mainLayout->addWidget(rotateRight);
    QWidget* widget = new QWidget(nullptr, Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    widget->setWindowOpacity(0.8);
    widget->setLayout(mainLayout);
    widget->setGeometry(QRect(100, 100, 100, 100));
    scene.addWidget(widget);
    CustomView w;
    w.resize(1080, 720);
    w.setScene(&scene);
    QObject::connect(zoomIn, &QPushButton::clicked, &w, &CustomView::zoomIn);
    QObject::connect(zoomOut, &QPushButton::clicked, &w, &CustomView::zoomOut);
    QObject::connect(rotateLeft, &QPushButton::clicked, &w, &CustomView::rotateLeft);
    QObject::connect(rotateRight, &QPushButton::clicked, &w, &CustomView::rotateRight);
    w.show();
    return a.exec();
}

测试代码的效果如下:
在这里插入图片描述

2、碰撞检测

在Qt中,QGraphicsView是一个用于显示图形场景(QGraphicsScene)的组件。它提供了一些方便的方法,用于检测图形项(QGraphicsItem)之间的碰撞。
QGraphicsView的碰撞检测原理是基于图形项的包围盒(bounding box)计算的。每个图形项都有一个包围盒,用于描述其在场景中的位置和大小。当一个图形项的包围盒与另一个图形项的包围盒相交时,就可以判断它们发生了碰撞。
QGraphicsView提供了两种方法来执行碰撞检测:

  • QGraphicsItem::collidesWithItem()方法:这个方法用于检测两个图形项之间是否发生了碰撞。它会检查两个图形项的包围盒是否相交,如果相交则返回true,否则返回false。
  • QGraphicsScene::collidingItems()方法:这个方法用于查找与指定图形项发生碰撞的其他图形项。它会在场景中查找与指定图形项相交的其他图形项,并将它们返回。

如下两个矩形图元碰撞产生新的矩形图元的测试代码:

#include "PengZhuang.h"
#include <QtWidgets/QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QBrush>
#include <QPen>
#include<QTimer>
#include <QDebug>
#include<QMouseEvent>

class MyView : public QGraphicsView
{
public:
    explicit MyView(QWidget *parent=nullptr) : QGraphicsView(parent){}
protected:
    virtual void mousePressEvent(QMouseEvent* ev) override
    {
        //创建两个矩形图元
        QGraphicsRectItem* rect1 = new QGraphicsRectItem(0, 0, 50, 50);
        QGraphicsRectItem* rect2 = new QGraphicsRectItem(100, 100, 70, 70);
        rect1->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
        rect2->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
        //将图元添加到场景中
        this->scene()->addItem(rect1);
        this->scene()->addItem(rect2);
        //检测到矩形碰撞,产生新的矩形
        QGraphicsRectItem* newRect = nullptr;
        if (rect1->collidesWithItem(rect2))
        {
            qreal x = rect1->rect().x() < rect2->rect().x() ? rect1->rect().x() : rect2->rect().x();
            qreal y = rect1->rect().y() < rect2->rect().y() ? rect1->rect().y() : rect2->rect().y();
            int width=rect1->rect().x() + rect1->rect().width() > rect2->rect().x() + rect2->rect().width()
                ? rect1->rect().x() + rect1->rect().width() - x : rect2->rect().x() + rect2->rect().width() - x;
            int height= rect1->rect().y() + rect1->rect().height() > rect2->rect().y() + rect2->rect().height() ?
                rect1->rect().y() + rect1->rect().height() - y : rect2->rect().y() + rect2->rect().height() - y;
            newRect = new QGraphicsRectItem(x, y, width, height);
            this->scene()->addItem(newRect);
        }
        QGraphicsView::mousePressEvent(ev);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyView view;
    view.setScene(new QGraphicsScene(0, 0, 300, 300));
    view.resize(1080, 720);
    view.show();
    PengZhuang w;
    w.show();
    return a.exec();
}

测试代码的效果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值