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

QGraphics类型学习使用【Qt】【C++】

QGraphics类型学习使用

  • 需求
  • 过程
  • 全部完整代码

  首先已知,QGraphicsView,QGraphicsScene, QGraphicsItem,分别称为:视图,场景,图元,图表就是各种各样的元素,图片元素,线条元素,等等,场景就是容纳图元的一个容器,场景不会显示出来,这句话很关键。若是想将其显示到屏幕上,需要将场景设置到视图中,由视图负责显示。

需求

  利用QGraphics家族类成员实现将图片显示出来,并对图片进行旋转,伸缩等操作。
以下是完成后的结果图:

过程

  首先创建了项目,并将图片添加进qrc资源文件(不添加也行,不影响):
在这里插入图片描述
  代码如下:

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent)
{QPixmap *pm = new QPixmap("://earth.jpg");QGraphicsView *view = new QGraphicsView(this);QGraphicsScene *scene = new QGraphicsScene;QGraphicsPixmapItem *pixmap = new QGraphicsPixmapItem(*pm);setGeometry({300,300, 800, 600});view->resize(pixmap->pixmap().width(),pixmap->pixmap().height());scene->addItem(pixmap);view->setScene(scene);QVBoxLayout *vLayout = new QVBoxLayout;QSlider *s1 = new QSlider(Qt::Horizontal);QSlider *s2 = new QSlider(Qt::Horizontal);vLayout->addWidget(s1);vLayout->addWidget(s2);QHBoxLayout *hLayout = new QHBoxLayout(this);hLayout->addWidget(view);hLayout->addLayout(vLayout);
}Widget::~Widget()
{
}

在这里插入图片描述
  可以看到只显示的图片的一部分,根据下面和右边的滚动条知道可以通过滑动来展示图片,
在这里插入图片描述
  溯源可知,由于QGraphicsView继承自QAbstractScrollArea,顾名思义,它的父类具有滚动功能,具体不深究,知道是因为那个部分带来的滚动条即可。
  但是我们的目的是显示所有图片的细节,可以放大图片:

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent)
{QPixmap *pm = new QPixmap("://earth.jpg");QPixmap newPm = pm->scaled(pm->width() / 1.5, pm->height() / 1.5);QGraphicsView *view = new QGraphicsView(this);QGraphicsScene *scene = new QGraphicsScene;QGraphicsPixmapItem *pixmap = new QGraphicsPixmapItem(newPm);setGeometry({500,500, pixmap->pixmap().width()+100,pixmap->pixmap().height()});view->resize(pixmap->pixmap().width(),pixmap->pixmap().height()- 100);scene->addItem(pixmap);view->setScene(scene);QVBoxLayout *vLayout = new QVBoxLayout;QSlider *s1 = new QSlider(Qt::Horizontal);QSlider *s2 = new QSlider(Qt::Horizontal);vLayout->addWidget(s1);vLayout->addWidget(s2);QHBoxLayout *hLayout = new QHBoxLayout(this);hLayout->addWidget(view);hLayout->addLayout(vLayout);
}Widget::~Widget()
{
}

得到:
在这里插入图片描述

  将右侧滚动条大小进行调整,整体大小进行调整:

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent)
{QPixmap *pm = new QPixmap("://earth.jpg");QPixmap newPm = pm->scaled(pm->width() / 1.5, pm->height() / 1.5);QGraphicsView *view = new QGraphicsView;QGraphicsScene *scene = new QGraphicsScene;QGraphicsPixmapItem *pixmap = new QGraphicsPixmapItem(newPm);setGeometry({500,500, pixmap->pixmap().width()+100,pixmap->pixmap().height()});view->resize(pixmap->pixmap().width(),pixmap->pixmap().height()- 100);scene->addItem(pixmap);view->setScene(scene);QVBoxLayout *vLayout = new QVBoxLayout;QSlider *s1 = new QSlider(Qt::Horizontal);QSlider *s2 = new QSlider(Qt::Horizontal);QHBoxLayout *gbox1 = new QHBoxLayout;QHBoxLayout *gbox2 = new QHBoxLayout;QLabel *label1 = new QLabel("旋转:");QLabel *label2 = new QLabel("伸缩:");gbox1->addWidget(label1);gbox1->addWidget(s1);gbox2->addWidget(label2);gbox2->addWidget(s2);vLayout->addLayout(gbox1);vLayout->addLayout(gbox2);QHBoxLayout *hLayout = new QHBoxLayout(this);hLayout->addWidget(view);hLayout->addLayout(vLayout);
}Widget::~Widget()
{
}

在这里插入图片描述
  接下来就可以设置旋转和缩放的槽函数了,两种方式:

  • 旋转视图:
void Widget::rotate(int value)
{view->rotate(value);update();
}
  • 旋转图元:
void Widget::rotate(int value)
{pixmap->setRotation(value);update();
}

此时发现问题:旋转中心点是左上角:
在这里插入图片描述

这是因为,在两种旋转函数中:

  • rotate: 旋转原点是以中心点为基准进行旋转的。
  • setRotation: 旋转原点是以左上角为基准进行旋转的。

所以需要修改旋转原点:
setTransformOriginPoint:这个函数通常用于设置QGraphicItem及其子类的变换中心点,可作为旋转,伸缩时的中心点。
所以:

void Widget::rotate(int value)
{pixmap->setTransformOriginPoint(pixmap->pixmap().width()/2, pixmap->pixmap().height()/2);pixmap->setRotation(value);update();
}

在这里插入图片描述
发现旋转没有一圈,设置一下滚动条的范围即可:s1->setRange(0,360);

接下来实现伸缩:

void Widget::scale(int value)
{pixmap->setTransformationMode(Qt::SmoothTransformation);pixmap->setScale(value);update();
}

运行后:
在这里插入图片描述
发现伸缩大小比例不对,将滚动条的范围设置为一个合适的范围:
s2->setRange(0,2);,设置后运行:
在这里插入图片描述
  发现slider的步长太大,但是我们需要的是0.1级别的调整,查询发现slider
  设置步长的函数为setSingleStep(int),只能设置最小为1的步长,因此我们重新调整,将范围设置为:s2->setRange(0,20);

void Widget::scale(int value)
{pixmap->setTransformationMode(Qt::SmoothTransformation);pixmap->setScale(value*1.0/10);update();
}

运行后发现;
在这里插入图片描述
  第1点是期望伸缩中心点是在图片的中心点,但是实际上是在图片左上角进行伸缩的,所以需要修该一下:pixmap->setTransformOriginPoint(pixmap->pixmap().width()/2, pixmap->pixmap().height()/2);
其实也就是将在这里插入图片描述
  rotate函数里面的这个setTransformOriginPoint放到构造函数中。

  第2点就是伸缩的时候是从slider的值改变的第一个量伸缩的,我们期待的是从当前值进行伸缩,接下来进行修改:
  因为涉及到缩小和放大,我们可以将slider的初始值设置为10,进过变换也就是1,即没有伸缩过的图片:
s2->setValue(10);
  slider位于中间,向左缩小,向右放大:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  自此代码简单完成。是自己学习路上的过程笔记,知识浅薄,或许不具备学习来使用。

全部完整代码

// widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QPixmap>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QSlider>
#include <QGroupBox>
#include <QLabel>
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
private:QGraphicsView *view;QGraphicsPixmapItem *pixmap;QGraphicsScene *scene;private slots:void rotate(int);void scale(int);};
#endif // WIDGET_H
// widget.cpp
#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent)
{QPixmap *pm = new QPixmap("://earth.jpg");QPixmap newPm = pm->scaled(pm->width() / 1.5, pm->height() / 1.5);view = new QGraphicsView;scene = new QGraphicsScene;pixmap = new QGraphicsPixmapItem(newPm);setGeometry({500,500, pixmap->pixmap().width()+100,pixmap->pixmap().height()});view->resize(pixmap->pixmap().width(),pixmap->pixmap().height()- 100);scene->addItem(pixmap);view->setScene(scene);QVBoxLayout *vLayout = new QVBoxLayout;QSlider *s1 = new QSlider(Qt::Horizontal);s1->setRange(0,360);QSlider *s2    = new QSlider(Qt::Horizontal);s2->setRange(0,20);s2->setValue(10);QHBoxLayout *gbox1 = new QHBoxLayout;QHBoxLayout *gbox2 = new QHBoxLayout;QLabel *label1 = new QLabel("旋转:");QLabel *label2 = new QLabel("伸缩:");gbox1->addWidget(label1);gbox1->addWidget(s1);gbox2->addWidget(label2);gbox2->addWidget(s2);vLayout->addLayout(gbox1);vLayout->addLayout(gbox2);QHBoxLayout *hLayout = new QHBoxLayout(this);hLayout->addWidget(view);hLayout->addLayout(vLayout);pixmap->setTransformOriginPoint(pixmap->pixmap().width()/2, pixmap->pixmap().height()/2);connect(s1, SIGNAL(valueChanged(int)), this, SLOT(rotate(int)));connect(s2, SIGNAL(valueChanged(int)), this, SLOT(scale(int)));
}Widget::~Widget()
{
}void Widget::rotate(int value)
{pixmap->setTransformOriginPoint(pixmap->pixmap().width()/2, pixmap->pixmap().height()/2);pixmap->setRotation(value);update();
}void Widget::scale(int value)
{pixmap->setTransformationMode(Qt::SmoothTransformation);pixmap->setScale(value*1.0/10);update();
}

         新人创作不易,你的点赞和关注都是对我莫大的鼓励,再次感谢您的观看。

http://www.lryc.cn/news/467078.html

相关文章:

  • 迁移学习和在线学习小结
  • 克里金插值(Kriging interpolation)
  • sealed class-kotlin中的封闭类
  • MongoDB Shell 基本命令(一)
  • Flink时间语义和时间窗口
  • 在wpf中登录成功之后怎么设置主页布局及点击不同的菜单跳转到不同的页面,这个是我们做wpf项目必要会的一个功能
  • 基于opencv的人脸闭眼识别疲劳监测
  • aeo认证需要什么材料
  • 【iOS】YYModel
  • Cadence元件A属性和B属性相互覆盖
  • 【火山引擎】语音合成 | HTTP接口 | 一次性合成 | python
  • YOLOv11改进-卷积-空间和通道重构卷积SCConv
  • 记录一次从nacos配置信息泄露到redis写计划任务接管主机
  • Unity加载界面制作
  • 最好的ppt模板网站是哪个?做PPT不可错过的18个网站!
  • 煤矿安全监测监控作业题库
  • 【记录】Django数据库的基础操作
  • XHCI 1.2b 规范摘要(五)
  • 小程序短链接生成教程
  • C++进阶之路:再谈构造函数、static成员、友元(类与对象_下篇)
  • C 函数指针与回调函数
  • CTF(九)
  • 三种单例实现
  • Spring XML配置方式和Spring Boot注解方式的详细对照关系
  • leetcode 无重复字符串的排列和组合
  • 7. 配置
  • WPF中Grid、StackPanel、Canvas、WrapPanel的区别
  • 昇思MindSpore进阶教程--开发常见问题
  • 【Linux】Linux进程地址空间
  • 创建包含可导入浏览器信任的SSL自签名证书