QT学习之图形绘制

这篇博客介绍了QT的基础绘图,重点讲解了如何在QT中显示SVG格式的可缩放矢量图形,以及探讨了QT Graphics View框架,包括场景QGraphicsScene、视图QGraphicsView和图元QGraphicsItem的使用。内容涵盖了Graphics View的坐标转换、缩放功能,以及如何创建自定义动画图元和实现图元的旋转、缩放、切变和位移。同时,还提到了QT中定时器的使用方法。

QT基础绘图

 //.h
Class DiyDraw: public QWidget
{
    Q_OBJECT
piblic:
    explicit DiyDraw(QWidget* parent=0);
    void mousePressEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);
    void paintEvent(QPaintEvent* event);  //重绘函数
    void resizeEvent(QResizeEvent* event);
signals:
public slots:
    void clear();
protected:
private:
    QPixmap* pixmap;
    QPoint startPos;
    QPoint endPos;
}
//.cpp
DiyDraw::DiyDraw(QWidget* parent): QWidget(parent)
{
    setAutoFillBackground(true);
    setPalette(QPalette(Qt::white));
    pixmap=new QPixmap(size());  //用于接收绘制内容
    pixmap->fill(Qt::white);
}
void DiyDraw::mousePressEvent(QMouseEvent* event)
{
    startPos=event->pos();
}
void DiyDraw::mouseMoveEvent(QMouseEvent* event)
{
    QPainter* painter=new QPainter;
    QPen pen;
    pen.setColor(QColor(Qt::red));
    painter->begin(pixmap);
    painter->setPen(pen);
    painter->drawLine(startPos, event->pos());
    painter->end();
    startPos=event->pos();
    update();
}
void DiyDraw::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    painter.drawPixmap(QPoint(0,0), *pixmap);
}
void DiyDraw::resizeEvent(QResizeEvent* event)
{
    if((height()>pixmap->height())||(width()>pixmap->width()))
    {
        QPixmap* newPixmap=new QPixmap(size());
        newPixmap->fill(Qt::white);
        QPainter painter(newPixmap);
        painter.drawPixmap(QPoint(0,0), *pixmap);
        pixmap=newPixmap;
    }
    QWidget::resizeEvent(event);
}
void DiyDraw::clear()
{
   QPixmap* nullPixmap=new QPixmap(size());
   nullPixmap->fill(Qt::white);
   pixmap=nullPixmap;
   update();
}

QT显示SVG格式图片(可缩放矢量图形)

 //.h
Class DiySvgWidget: public QSvgWidget
{
    Q_OBJECT
piblic:
    DiySvgWidget(QWidget* parent=0);
    void wheelEvent(QWheelEvent* event);
signals:
public slots:
protected:
private:
    QSvgRenderer* render;
}
//.cpp
DiySvgWidget::DiySvgWidget(QWidget* parent): QWidget(parent)
{
    load("diySvg.svg");
    render=renderer();
}
void DiySvgWidget::wheelEvent(QWheelEvent* event)
{
    const double offset=0.1;
    int width=render->defaultSize().width();
    int height=render->defaultSize().height();
    if(event->delta>0)
    {
        width=int(width+width*offset);
        height=int(height+height*offset);
    }
    else
    {
        width=int(width-width*offset);
        height=int(height-height*offset);
    }
    resize(width, height);
}

QT Graphics View图形视图框架
在QT5中Graphics View取代QCanvas,提供基于图元的模型/视图编程。
Graphics View框架结构包含场景类QGraphicsScene、视图类QGraphicsView和图元类QGraphicsItem三元素,场景类提供了一个用于管理位于其中的众多图元的容器,视图类用于显示场景中的图元,一个场景可以通过多个视图表现,一个场景包括多个几何图形。
Graphics View模型视图框架及坐标转换、缩放等基本功能:
QPointF与QPoint:QPoint表示一个平面上整数精度的点坐标,可以通过x(),y()等函数方便的进行存取操作;QPointF在浮点精度上表征平面上的点。

//.h
Class DiyView: public QGraphicsView
{
   Q_OBJECT
piblic:
   DiyView();
signals:
public slots:
   void slotZoom(int value);
protected:    
   void drawBackground(QPainter* painter, const QRectF &rect);
   void mouseMoveEvent(QMouseEvent* event);
   QPointF mapToMap(QPointF P);
private:
   int zoomMiddle;
   QPixmap pixmap;
   /* 经纬度坐标点 */
   qreal topLeftX;  
   qreal topLeftY;
   qreal bottomRightX;
   qreal bottomRightY;
}
//.cpp
DiyView::DiyView()
{
   QGraphicsScene* scene=new QGraphicsScene(this);
   scene->setSceneRect(-pixmap.width()/2, -pixmap.height()/2, pixmap.width(), pixmap.height());
   setScene(scene);
   setCacheMode(CacheBackground);
}
/* 以图片重绘场景背景实现图片显示 */
void DiyView::drawBackground(QPainter *painter, const QRectF &rect)
{
   painter->drawPixmap(int(sceneRect().left(), int(sceneRect().top()), pixmap);
}
void DiyView::slotZoom(int value)
{
   qreal s;
   if(value>zoomMiddle)  //放大
   {
       s=pow(1.01, (value-zoomMiddle));
   }
   else
   {
       s=pow(1/1.01, (zoomMiddle-value));
   }
   scale(s, s);
   zoomMiddle=value;
}
void DiyView::mouseMoveEvent(QMouseEvent* event)
{
   QPoint viewPoint=event->pos();
   QPointF scenePoint=mapToScene(viewPoint);
   QPointF latLon=mapToMap(scenePoint);   
}
/*  经纬度转换 */
QPointF DiyView::mapToMap(QPointF P)
{    
   QPointF latLon;
   qreal h=sceneRect().height();
   qreal w=sceneRect().width();
   qreal lon=topLeftY-((h/2+p.y())*abs(topLeftY-bottomRightY)/h);
   qreal lat=topLeftX-((w/2+p.x())*abs(topLeftX-bottomRightX)/w);
   latLon.setX(lat);
   latLon.setY(lon);
}

自定义动画图元:
利用定时器和图元的重绘函数paint()实现图元的动画效果

//.h
Class DiyFlashItem: public QObject, public QGraphicsItem
{
   Q_OBJECT
piblic:
   explicit DiyFlashItem(QObject* parent=0);
   void timerEvent(QTimerEvent*);  //定时器函数
   QRectF boundingRect() const;  //图元限定区域,所有继承自QGraphicsItem的类,都需实现此函数
signals:
public slots:
protected:
   /* 重绘函数 */
   void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
private:
   bool flash;
   QPixmap pixmap;
}
//.cpp
DiyFlashItem::DiyFlashItem(QObject* parent=0): QObject(parent)
{
   flash=true;
   starTimer(1000);
}
QRectF DiyFlashItem::boundingRect() const
{
   qreal adjust=2;
   return QRectF(-pixmap.width()/2-adjust, -pixmap.height()/2-adjust, 
       pixmap.width()+adjust*2, pixmap.height()+adjust*2);
}
void DiyFlashItem::timerEvent(QTimerEvent*)
{
   flash=!flash;
   update();  //反置后,调用update()函数,重绘图元以实现闪烁
}
void DiyFlashItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
   painter->setPen(QColor(Qt::balck, 0));
   painter->setBrush(flash?(Qt::red):(Qt::blue));
   painter->drawRect(-pixmap.width()/2, -pixmap.height()/2,
       pixmap.width(), pixmap.height());
}

图元的旋转、缩放、切变、位移:

void slotRotate(int value)
{
   diyView->rotate(value-angle);
   angle=value;
}
void slotScale(int value)
{
   slotZoom(value);
}
void slotShear(int value)
{
   view->shera((value-shearValue)/10.0, 0);
   shearValue=value;
}
void slotTranslate(int value)
{
   view->translate((value-translateValue), (value-translateValue));
   translateValue=value;
}

其中,QT中定时器的使用方法:
(1)重载timerEvent(QTimerEvent *)函数,然后再在类的构造函数中设置时间间隔

  startTimer(50);  //单位为毫秒

(2)在类的构造函数中设定如下:

  QTimer *timer=new QTimer(this);
  connect(timer,SIGNAL(timeout()),this,SLOT(timeoutslot()));//timeoutslot()为自定义槽
  timer->start(1000);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值