QGraphicsView使用范例汇总:入门篇

1、对视图实现缩放、旋转、切变(扭曲)和平移

2、添加基本图元(矩形、圆形、图片、文字)和自定义图元、动画效果

1、实现对视图GraphicView的缩放

//MapWidget派生于QGraphicsView
MapWidget::MapWidget()
{
	//用于地图缩放的滑动条
	QSlider *slider = new QSlider;
	slider->setOrientation(Qt::Vertical);
	slider->setRange(1,100);
	slider->setTickInterval(10);
	slider->setValue(50);
	connect(slider,SIGNAL(valueChanged(int)),this,SLOT(slotZoom(int)));
}


void MainWidget::slotRotate(int value)
{
    view->rotate(value-angle);
    angle = value;
}

void MainWidget::slotScale(int value)
{
    qreal s;
    if(value>scaleValue)
        s=pow(1.1,(value-scaleValue));
    else
        s=pow(1/1.1,(scaleValue-value));
    view->scale(s,s);
    scaleValue=value;
}

//扭曲
void MainWidget::slotShear(int value)
{
    view->shear((value-shearValue)/10.0,0);
    shearValue=value;
}

//平移
void MainWidget::slotTranslate(int value)
{
    view->translate(value-translateValue,value-translateValue);
    translateValue=value;
}

2、向GraphicsScene中添加各种元素,包括文字、图片、矩形、三角形等

//在MainWindow中的构造函数中
MainWindow::MainWindow(QWidget* parent)
{
    //创建一个场景,用于对元素的管理
    scene = new QGraphicsScene;
    scene->setSceneRect(-200,-200,400,400);

    //创建一个视图,用于显示一部分scene
    QGraphicsView *view = new QGraphicsView;
    view->setScene(scene);
    view->setMinimumSize(400,400);
    view->show();
}

void MainWindow::clearItem()        	//清除场景中所有的图元
{
    QList<QGraphicsItem*> listItem = scene->items();

    while(!listItem.empty())
    {
        scene->removeItem(listItem.at(0));
        listItem.removeAt(0);
    }
}

void MainWindow::slotAddEllipseItem() 	//在场景中加入一个椭圆形图元
{
    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(QRectF(0,0,80, 60));
    item->setPen(Qt::NoPen);
    item->setBrush(QColor(qrand()%256,qrand()%256,qrand()%256));
    item->setFlag(QGraphicsItem::ItemIsMovable);

    scene->addItem(item);
    item->setPos((qrand()%int(scene->sceneRect().width()))-200,(qrand()%int(scene->sceneRect().height()))-200);
}

void MainWindow::slotAddPolygonItem()   //在场景中加入一个多边形图元
{
    QVector<QPoint> v;
    v<<QPoint(30,-15)<<QPoint(0,-30)<<QPoint(-30,-15)<<QPoint(-30,15)<<QPoint(0,30)<<QPoint(30,15);
    QGraphicsPolygonItem *item = new QGraphicsPolygonItem(QPolygonF(v));
    item->setBrush(QColor(qrand()%256,qrand()%256,qrand()%256));
    item->setFlag(QGraphicsItem::ItemIsMovable);

    scene->addItem(item);
    item->setPos((qrand()%int(scene->sceneRect().width()))-200,(qrand()%int(scene->sceneRect().height()))-200);
}


void MainWindow::slotAddTextItem()      //在场景中加入一个文字图元
{
    QFont font("Times",16);
    QGraphicsTextItem *item = new QGraphicsTextItem("Hello Qt");
    item->setFont(font);
    item->setFlag(QGraphicsItem::ItemIsMovable);
    item->setDefaultTextColor(QColor(qrand()%256,qrand()%256,qrand()%256));
    scene->addItem(item);
    item->setPos((qrand()%int(scene->sceneRect().width()))-200,(qrand()%int(scene->sceneRect().height()))-200);
}

void MainWindow::slotAddRectItem()      //在场景中加入一个长方形图元
{
    QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0,0,60,60));
    QPen pen;
    pen.setWidth(3);
    pen.setColor(QColor(qrand()%256,qrand()%256,qrand()%256));
    item->setPen(pen);
    item->setBrush(QColor(qrand()%256,qrand()%256,qrand()%256));
    item->setFlag(QGraphicsItem::ItemIsMovable);

    scene->addItem(item);
    item->setPos((qrand()%int(scene->sceneRect().width()))-200,(qrand()%int(scene->sceneRect().height()))-200);
}

void MainWindow::slotAddAlphaItem()    	//在场景中加入一个透明蝴蝶图片
{
    QGraphicsPixmapItem *item =scene->addPixmap(QPixmap("image.png"));
    item->setFlag(QGraphicsItem::ItemIsMovable);
    item->setPos((qrand()%int(scene->sceneRect().width()))-200,(qrand()%int(scene->sceneRect().height()))-200);
}

        向场景中添加自定义图元对于自定义的图元需要注意的是

        1)如果需要使用Qt的特性,在多重继承当中,一定要将QObject写在QGraphicsItem前面:class CustomItem: public QObject, public QGraphicsItem

        2)相关的函数需要重载:boundingRect和paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)

        下面是自定义圆形的demo,实现了定时闪烁:

void MainWindow::slotAddFlashItem()  	//在场景中加入一个闪烁图元
{
    FlashItem *item = new FlashItem;
    scene->addItem(item);
    item->setPos((qrand()%int(scene->sceneRect().width()))-200,(qrand()%int(scene->sceneRect().height()))-200);
}
#ifndef FLASHITEM_H
#define FLASHITEM_H

#include <QObject>
#include <QGraphicsItem>
#include <QPainter>

class FlashItem : public QObject,public QGraphicsItem
{
    Q_OBJECT
public:
    explicit FlashItem(QObject *parent = 0);
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    void timerEvent(QTimerEvent *);
private:
    bool flash;
    QTimer *timer;
signals:
    
public slots:
    
};

#endif // FLASHITEM_H




#include "flashitem.h"

FlashItem::FlashItem(QObject *parent) :
    QObject(parent)
{
    flash=true;
    setFlag(ItemIsMovable);
    startTimer(1000);
}

QRectF FlashItem::boundingRect() const
{
    qreal adjust = 2;
    return QRectF(-10-adjust,-10-adjust,43+adjust,43+adjust);
}

void FlashItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setPen(Qt::NoPen);
    painter->setBrush(Qt::darkGray);
    painter->drawEllipse(-7,-7,40,40);

    painter->setPen(QPen(Qt::black,0));
    painter->setBrush(flash?(Qt::red):(Qt::yellow));
    painter->drawEllipse(-10,-10,40,40);
}

void FlashItem::timerEvent(QTimerEvent *)
{
    flash=!flash;
    update();
}

        向场景中添加动画图元:动画效果是沿着直线轨迹反复/来回运动

void MainWindow::slotAddAnimationItem() //在场景中加入一个动画星星
{
    StartItem *item = new StartItem;
    QGraphicsItemAnimation *anim = new QGraphicsItemAnimation;
    anim->setItem(item);
    QTimeLine *timeLine = new QTimeLine(4000);
    timeLine->setCurveShape(QTimeLine::SineCurve);
    timeLine->setLoopCount(0);

    anim->setTimeLine(timeLine);

    int y =(qrand()%400)-200;
    for(int i=0;i<400;i++)
    {
        anim->setPosAt(i/400.0,QPointF(i-200,y));
    }
    timeLine->start();
    scene->addItem(item);
}
#ifndef STARTITEM_H
#define STARTITEM_H

#include <QGraphicsItem>
#include <QPainter>

class StartItem : public QGraphicsItem
{
public:
    StartItem();
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

private:
    QPixmap pix;
};

#endif // STARTITEM_H



#include "startitem.h"

StartItem::StartItem()
{
    pix.load("star.png");
}

QRectF StartItem::boundingRect() const
{
    return QRectF(-pix.width()/2,-pix.height()/2,pix.width(),pix.height());
}

void StartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{
    painter->drawPixmap(boundingRect().topLeft(),pix);
}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
QGraphicsView::RubberBandDrag 是 QGraphicsView 类中的一个枚举值,用于设置 QGraphicsView 组件中拖动时的橡皮筋效果。具体来说,当用户在 QGraphicsView 组件中拖动鼠标时,如果设置了 QGraphicsView::RubberBandDrag,则会出现一个橡皮筋矩形,用于指示当前选择的区域。 要模拟画出 QGraphicsView::RubberBandDrag 的效果,可以参考以下步骤: 1. 创建一个 QGraphicsView 组件,并设置其拖动模式为 QGraphicsView::RubberBandDrag。 2. 重写 QGraphicsView 的 mousePressEvent、mouseMoveEvent 和 mouseReleaseEvent 事件,以实现橡皮筋效果。 3. 在 mousePressEvent 事件中记录下鼠标按下的位置,然后在 mouseMoveEvent 事件中计算出当前鼠标位置与按下位置之间的矩形,将该矩形传递给 QGraphicsView 的 rubberBandRect 方法,用于绘制橡皮筋矩形。 4. 在 mouseReleaseEvent 事件中清除橡皮筋矩形。 下面是一个简单的实现示例: ```cpp class MyGraphicsView : public QGraphicsView { public: MyGraphicsView(QWidget *parent = nullptr) : QGraphicsView(parent) { setDragMode(QGraphicsView::RubberBandDrag); } protected: void mousePressEvent(QMouseEvent *event) override { m_origin = event->pos(); QGraphicsView::mousePressEvent(event); } void mouseMoveEvent(QMouseEvent *event) override { QRectF rect(m_origin, event->pos()); setRubberBandRect(rect); QGraphicsView::mouseMoveEvent(event); } void mouseReleaseEvent(QMouseEvent *event) override { setRubberBandRect(QRect()); QGraphicsView::mouseReleaseEvent(event); } private: QPoint m_origin; }; ``` 在上面的示例中,我们重写了 QGraphicsView 的三个事件处理函数,并在其中实现了橡皮筋效果。其中 m_origin 记录了鼠标按下的位置,setRubberBandRect 方法用于设置橡皮筋矩形的区域。最终,在 mouseReleaseEvent 中清除橡皮筋矩形即可。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值