图元(QGraphicsItem):图元是场景中绘制的基本元素,可以是图形、文本、图像等。每个图元都有自己的属性,例如位置、变换矩阵、颜色等。通过使用不同类型的图元,我们可以创建各种复杂的图形。
创建图元类继承QGraphicsItem
pixitem.h
#ifndef PIXITEM_H
#define PIXITEM_H
#include <QGraphicsItem> // 图元类
#include <QPixmap>
#include <QPainter>
class PixItem : public QGraphicsItem
{
public:
PixItem(QPixmap *pixmap);
private:
QPixmap pix;
public:
// 此函数只刷新固定区域,重新实现:返回调整成实际物体所在位置的包含区域
QRectF boundingRect() const;
// 绘制操作
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};
#endif // PIXITEM_H
pixitem.cpp
#include "pixitem.h"
PixItem::PixItem(QPixmap *pixmap)
{
pix=*pixmap;
}
// 此函数只刷新固定区域,重新实现:返回调整成实际物体所在位置的包含区域
QRectF PixItem::boundingRect() const
{
return QRectF(-2-pix.width()/2,-2-pix.height()/2,pix.width()+4,pix.height()+4);
}
// 绘制操作
void PixItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->drawPixmap(-pix.width()/2,-pix.height()/2,pix);
}
场景(QGraphicsScene):场景是一种容器,它可以管理图元并提供一些高级的功能,例如鼠标点击事件、图元选择、复制/粘贴等。场景还可以提供支持视图中显示的内容大小的视口(Viewport)。场景的中心原点坐标在窗口的中心点
视图(QGraphicsView):视图是用于在窗口中显示场景内容的控件。视图可以对场景进行缩放、平移等操作,还可以与鼠标和键盘事件相交互。视图还可以使用自定义的渲染器对图元进行渲染,支持OpenGL渲染。视图坐标原点在窗口左上角
在mainwidget.h中创建场景,视图
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
#include <QGraphicsView> // 视图
#include <QGraphicsScene> // 场景
#include <QFrame>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QSlider>
#include "pixitem.h"
#include <math.h>
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = nullptr);
~MainWidget();
public:
void CreateControlFrameFunc(); // 创建控件框架
private:
int iAngle; // 角度
qreal scalevalues; // 缩放
qreal leanvalues; // 倾斜
QGraphicsView *view; // 视图对象
QFrame *controlframe; // 控制边框样式
PixItem *pixitem;
private slots:
void rotateFunc(int); // 旋转
void scaleFunc(int); // 缩放
void leanFunc(int); // 倾斜
};
#endif // MAINWIDGET_H
mainwidget.cpp
#include "mainwidget.h"
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
setWindowTitle("GraphicsView图形视图架构");
iAngle=3;
scalevalues=3;
leanvalues=3;
// 场景
QGraphicsScene *sence=new QGraphicsScene;
sence->setSceneRect(-200,-200,380,380);
QPixmap *pixmap=new QPixmap("d:\\3.png");
// 图元
pixitem=new PixItem(pixmap);
sence->addItem(pixitem); // 将图元添加到场景
pixitem->setPos(0,0);
// 视图
view=new QGraphicsView; // new视图
view->setScene(sence);
view->setMinimumSize(800,600);
controlframe=new QFrame;
CreateControlFrameFunc();
// 主窗体布局设计
QHBoxLayout *hlayout=new QHBoxLayout;
hlayout->addWidget(view);
hlayout->addWidget(controlframe);
setLayout(hlayout); // 向布局中添加子布局
}
MainWidget::~MainWidget()
{
}
void MainWidget::rotateFunc(int val) // 旋转
{
view->rotate(val-iAngle);
iAngle=val;
}
void MainWidget::scaleFunc(int val) // 缩放
{
qreal qs;
if(val>scalevalues)
qs=pow(1.1,(val-scalevalues));
else
qs=pow(1/1.1,(scalevalues-val));
view->scale(qs,qs);
scalevalues=val;
}
void MainWidget::leanFunc(int val) // 倾斜
{
view->shear((val-leanvalues)/2.0,0);
leanvalues=val;
}
void MainWidget::CreateControlFrameFunc() // 创建控件框架
{
// 旋转
QSlider *rotatesilder=new QSlider;
rotatesilder->setOrientation(Qt::Horizontal);
rotatesilder->setRange(0,360);
QHBoxLayout *rotatelayout=new QHBoxLayout;
rotatelayout->addWidget(rotatesilder);
QGroupBox *rotategroup=new QGroupBox("图形旋转");
rotategroup->setLayout(rotatelayout);
// 缩放
QSlider *scalesilder=new QSlider;
scalesilder->setOrientation(Qt::Horizontal);
scalesilder->setRange(0,2*scalevalues);
scalesilder->setValue(scalevalues);
QHBoxLayout *scalelayout=new QHBoxLayout;
scalelayout->addWidget(scalesilder);
QGroupBox *scalegroup=new QGroupBox("图形缩放");
scalegroup->setLayout(scalelayout);
// 倾斜
QSlider *leansilder = new QSlider;
leansilder->setOrientation(Qt::Horizontal);
leansilder->setRange(0,2*leanvalues);
leansilder->setValue(leanvalues);
QHBoxLayout *leanlayout = new QHBoxLayout;
leanlayout->addWidget(leansilder);
QGroupBox *leangroup = new QGroupBox(tr("图形倾斜"));
leangroup->setLayout(leanlayout);
// 信号与槽函数连接
connect(rotatesilder,SIGNAL(valueChanged(int)),this,SLOT(rotateFunc(int)));
connect(scalesilder,SIGNAL(valueChanged(int)),this,SLOT(scaleFunc(int)));
connect(leansilder,SIGNAL(valueChanged(int)),this,SLOT(leanFunc(int)));
// 控制面板设计布局
QVBoxLayout *vlayoutframe=new QVBoxLayout;
vlayoutframe->addWidget(rotategroup);
vlayoutframe->addWidget(scalegroup);
vlayoutframe->addWidget(leangroup);
controlframe->setLayout(vlayoutframe);
}