Qt5开发从入门到精通——第七篇六节( 图形视图—— 图元的旋转、缩放、切变、和位移)

CSDN话题挑战赛第2期
参赛话题:学习笔记

欢迎小伙伴的点评✨✨,相互学习、互关必回、全天在线🍳🍳🍳
博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩‍🚀

前言

本章节会给大家带来基于图元的旋转、缩放、切变、和位移。

QGraphicsltem类概述

它是场景中各个图元的基类,在它的基础上可以继承出各种图元类, Qt 已经预置的包括直线 (QGraphicsLineltem) 、椭圆 (QGraphicsEllipseltem) 、文本图元 (QGraphicsTextltem) 、矩形(QGraphicsRectltem) 等。当然,也可以在 QGraphicsltem 类的基础上实现自定义的图元类,即用户可以继承 QGraphicsltem 实现符合自己需要的图元。

二、 效果实例

图一
将图片Pointer.png、Clock.png放入到构建文件当中build-ItemWidget-Desktop_Qt_5_12_2_MinGW_32_bit-Debug
在这里插入图片描述

三、原码解析

mainwidget.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QWidget>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QFrame>
#include <QHBoxLayout>
#include <QSlider>
#include <QGroupBox>
#include <math.h>
#include "pixltem.h"
class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();
    void createControlFrame();
private:

   int angle;
   qreal scaleValue;
   qreal shearValue;
   qreal translateValue;
   QGraphicsView *view;
   QFrame *ctrlFrame;
   PixItem *pixItem;
   PixItem *pixItemL;
   QGraphicsScene *scene;


public slots:
void slotRotate(int);
void slotScale(int);
void slotShear(int);
void slotTranslate(int);

};

#endif // MAINWINDOW_H

pixltem.h

#ifndef PIXLTEM_H
#define PIXLTEM_H

#include <QGraphicsItem>
#include <QPixmap>
#include <QPainter>
class PixItem : public QGraphicsItem
{
public:
    PixItem(QPixmap *pixmap);
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
private:
    QPixmap pix;   //作为图元显示的图片

};

#endif // PIXLTEM_H

main.cpp

#include "mainwidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWidget w;
    w.show();

    return a.exec();
}

mainwidget.cpp

#include "mainwidget.h"

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{

    angle= 0;
    scaleValue = 5;
    shearValue = 5;
    translateValue = 50;
    scene= new QGraphicsScene;
    //限定新建 QGraphicsScene 对象的显示区域
    scene->setSceneRect(-200,-200,400,400);
    QPixmap *pixmapL =new QPixmap("Pointer.png");

    QPixmap *pixmap = new QPixmap ("Clock.png");
    pixItem = new PixItem(pixmap);  //新建一个自定义图元 Pixltem 对象,为它传入一个图片用于显示
    scene->addItem(pixItem);
    pixItem->setPos (0,0) ;


    pixItemL = new PixItem(pixmapL); //新建一个自定义图元 Pixltem 对象,为它传入一个图片用于显示
    scene->addItem(pixItemL);
    pixItemL->setPos(0,1);


    view= new QGraphicsView; //新建一个视图对象
    view->setScene (scene); //将视图对象与场景相连
    view->setMinimumSize(400,400); //设置视图的最小尺寸为 (400,400)
    ctrlFrame = new QFrame;  //新建主窗体右侧的控制面板区
    createControlFrame();
    //主窗口布局
    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->setMargin(10);
    mainLayout->setSpacing(20);
    mainLayout->addWidget(view);
    mainLayout->addWidget(ctrlFrame);
    setLayout(mainLayout);
    setWindowTitle(tr("Graphics Item Transformation"));
                                             //设置主窗口的标题



}

MainWidget::~MainWidget()
{

}

void MainWidget::createControlFrame()
{

    //旋转控制
    QSlider *rotateSlider = new QSlider;
    rotateSlider->setOrientation(Qt::Horizontal);
    rotateSlider->setRange(0,360);
    QHBoxLayout *rotateLayout = new QHBoxLayout;
    rotateLayout->addWidget(rotateSlider);
    QGroupBox *rotateGroup = new QGroupBox(tr("Rotate"));
    rotateGroup->setLayout(rotateLayout);

    //缩放控制
    QSlider *scaleSlider = new QSlider;
    scaleSlider->setOrientation(Qt::Horizontal);
    scaleSlider->setRange(0,2*scaleValue);
    scaleSlider->setValue(scaleValue);
    QHBoxLayout *scaleLayout = new QHBoxLayout;
    scaleLayout->addWidget(scaleSlider);
    QGroupBox *scaleGroup = new QGroupBox(tr("Scale"));
    scaleGroup->setLayout(scaleLayout);

    //切变控制

    QSlider *shearSlider = new QSlider;
    shearSlider->setOrientation(Qt::Horizontal);
    shearSlider->setRange(0,2*shearValue);
    shearSlider->setValue(shearValue);
    QHBoxLayout *shearLayout = new QHBoxLayout;
    shearLayout->addWidget(shearSlider);
    QGroupBox *shearGroup = new QGroupBox(tr("Shear"));
    shearGroup->setLayout(shearLayout);

    //位移控制
    QSlider *translateSlider = new QSlider;
    translateSlider->setOrientation(Qt::Horizontal);
    translateSlider->setRange(0,16*translateValue);
    translateSlider->setValue(translateValue);
    QHBoxLayout *translateLayout = new QHBoxLayout;
    translateLayout->addWidget(translateSlider);
    QGroupBox *translateGroup = new QGroupBox(tr("Translate"));
    translateGroup->setLayout(translateLayout);



    connect(rotateSlider,SIGNAL(valueChanged(int)),this,SLOT(slotRotate(int)));
    connect(scaleSlider,SIGNAL(valueChanged(int)),this,SLOT(slotScale(int)));
    connect(shearSlider,SIGNAL(valueChanged(int)),this,SLOT(slotShear(int)));
    connect(translateSlider,SIGNAL(valueChanged(int)),this,SLOT(slotTranslate(int)));

    //控制面板布局

    QVBoxLayout *frameLayout = new QVBoxLayout;
    frameLayout->setMargin(10);
    frameLayout->setSpacing(20);
    frameLayout->addWidget(rotateGroup);
    frameLayout->addWidget(scaleGroup);
    frameLayout->addWidget(shearGroup);
    frameLayout->addWidget(translateGroup);
    ctrlFrame->setLayout(frameLayout);


}
/*实现图元的旋转功能函数 slotRotate(), 主要是调用 QGraphicsView 类的 rotate()函数实现的,
它的参数为旋转角度值*/
void MainWidget::slotRotate(int value)
{


    view->rotate(value-angle);
    angle= value;
}

/*实现图元的缩放功能函数 slotScale(), 主要是调用 QGraphicsView 类的 scale() 函数实现的,它的参数为缩放的比例*/
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;
}

/*实现图元的切变功能函数 slotShearO, 主要是调用 QGraphicsView 类的 shear()函数实现的,
它的参数为切变的比例*/
void MainWidget::slotShear(int value)
{
    view->shear((value-shearValue)/10.0,0);
    shearValue=value;
}
/*实现图元的位移功能函数 slotTranslate(), 主要是调用 QGraphicsView 类的 translate()函数实
现的*/
void MainWidget::slotTranslate(int value)
{
    view->translate((value-translateValue)/2,(value-translateValue)/2);
    translateValue=value;
}


pixltem.cpp

#include "pixltem.h"

PixItem::PixItem(QPixmap *pixmap)
{
    pix= *pixmap;  //PixItem 的构造函数只是初始化了变量 pix
}

/*定义图元边界的函数 boundingRect(), 完成以图元坐标系为基础增加两个像素点的冗余的工
作。*/
QRectF PixItem::boundingRect () const
{
  return QRectF (-2-pix. width() /2, -2-pix. height() /2, pix. width() +4, pix.height()+4);
}

/*重画函数只需用 QPainter 的 dra'YPixmap()函数将图元图片绘出即可*/
void PixItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{
    painter->drawPixmap (-pix. width() /2, -pix. height() /2, pix);
}


四、总结

图形视图中图元的旋转、缩放、切变、和位移的动画效果会在应用程序开发中经常用到的

评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东.'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值