实现图元的旋转、缩放、切变和位移
效果:
mainwindow.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QFrame>
#include <QGraphicsView>
#include "pixitem.h"
#include <math.h>
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = nullptr);
~MainWidget();
public:
void createControlFrame();
private:
int angle;
qreal scaleValue;
qreal shearValue;
qreal translateValue;
QGraphicsScene *scene;
QGraphicsView *view;
QFrame *ctrlFrame;
PixItem *pixItem;
public slots:
void slotRotate(int);
void slotScale(int);
void slotShear(int);
void slotTranlate(int);
};
#endif // MAINWIDGET_H
mainwindow.cpp
#include "mainwidget.h"
#include <QSlider>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGroupBox>
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
setWindowTitle(QStringLiteral("Graphics Item Transformation"));
angle=0;
scaleValue=5;
shearValue=5;
translateValue=50;
scene=new QGraphicsScene(this);
scene->setSceneRect(-200,-200,400,400);
view=new QGraphicsView(this);
view->setScene(scene);
view->setMinimumSize(400,400);
QPixmap *pixmap=new QPixmap(":/new/butffly.png");
pixItem=new PixItem(pixmap); //新建一个pixitm图元,为它传一个图片用于显示
scene->addItem(pixItem);
pixItem->setPos(0,0);
ctrlFrame=new QFrame(this);
createControlFrame(); //新建主窗体右侧的面板
//主窗口布局
QHBoxLayout *mainLayout=new QHBoxLayout;
mainLayout->setMargin(10);
mainLayout->setSpacing(20);
mainLayout->addWidget(view);
mainLayout->addWidget(ctrlFrame);
this->setLayout(mainLayout); //设置布局
}
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(QStringLiteral("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(QStringLiteral("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(QStringLiteral("Shear"));;
shearGroup->setLayout(shearLayout);
//位移控制
QSlider *translateSlider=new QSlider;
translateSlider->setOrientation(Qt::Horizontal);
translateSlider->setRange(0,2*translateValue); //设置Slider的范围
translateSlider->setValue(translateValue);
QHBoxLayout *translateLayout= new QHBoxLayout;
translateLayout->addWidget(translateSlider);
QGroupBox *translateGroup=new QGroupBox(QStringLiteral("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(slotTranlate(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);
}
void MainWidget::slotRotate(int value)
{
view->rotate(value-angle);
angle=value;
}
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;
}
void MainWidget::slotShear(int value)
{
view->shear((value-shearValue)/10.0,0);
shearValue=value;
}
void MainWidget::slotTranlate(int value)
{
view->translate(value-translateValue,value-translateValue);
translateValue=value;
}
pixItem.h
#ifndef PIXITEM_H
#define PIXITEM_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 = nullptr) ;
private:
QPixmap pix; //作为图元显示的图片
};
#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);
/*inline void QPainter::drawPixmap(int x, int y, const QPixmap &pm)
{
drawPixmap(QPointF(x, y), pm);
}*/
}