当前位置: 首页 > news >正文

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


四、总结

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

相关文章:

  • 内网穿透工具natapp的注册、下载、安装与使用(详细教程)
  • CDH openssl 安装报错 TXT_DB error number 2
  • 【Linux线程同步专题】一、什么是线程同步、互斥量与死锁
  • 内网渗透-Linux权限维持
  • Git 便捷操作
  • 美国项目管理协会和埃森哲最新报告:越来越多的公司设立首席转型官一职
  • y145.第八章 Servless和Knative从入门到精通 -- 消息系统基础和Eventing及实践(九)
  • CDQ整体二分-三维偏序(陌上花开)
  • Vue3+elementplus搭建通用管理系统实例十三:添加树形选择器及多选功能
  • GBASE 8s 高可用配置参数
  • 大白话paxos raft
  • 微信小程序开发入门与实战(插槽及组件页面的生命周期)
  • QT 语言的学习 day09 进程 和 线程
  • Golang-02Golang变量与基本数据类型
  • 在线五子棋对战 --- 人机对战的实现
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • CentOS 7 修改主机名
  • CSS 专业技巧
  • iOS | NSProxy
  • IOS评论框不贴底(ios12新bug)
  • Java,console输出实时的转向GUI textbox
  • Java-详解HashMap
  • nginx 配置多 域名 + 多 https
  • node-glob通配符
  • spring学习第二天
  • 服务器从安装到部署全过程(二)
  • 高度不固定时垂直居中
  • 爬虫模拟登陆 SegmentFault
  • 数组大概知多少
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #android不同版本废弃api,新api。
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (过滤器)Filter和(监听器)listener
  • (六)Hibernate的二级缓存
  • (篇九)MySQL常用内置函数
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (三)Honghu Cloud云架构一定时调度平台
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .bat文件调用java类的main方法
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .Net IOC框架入门之一 Unity
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .NET运行机制
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • [ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹
  • [.net] 如何在mail的加入正文显示图片
  • [Android]一个简单使用Handler做Timer的例子
  • [BZOJ4554][TJOI2016HEOI2016]游戏(匈牙利)
  • [CentOs7]搭建ftp服务器(2)——添加用户
  • [codevs 1288] 埃及分数 [IDdfs 迭代加深搜索 ]
  • [Contiki系列论文之2]WSN的自适应通信架构