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