graphicsrectitem.h
#ifndef GRAPHICSRECTITEM_H
#define GRAPHICSRECTITEM_H
#include <QGraphicsItem>
#include "sizehandlerect.h"
class GraphicsRectItem : public QGraphicsItem
{
public:
GraphicsRectItem(const QRect & rect ,QGraphicsItem * parent);
QRectF boundingRect() const;
virtual void resizeTo(SizeHandleRect::Direction dir, const QPointF & point );
void move(const QPointF & point);
virtual Qt::CursorShape getCursor(SizeHandleRect::Direction dir );
SizeHandleRect::Direction hitTest( const QPointF & point ) const;
virtual QRectF rect() const;
virtual void updateGeometry();
QRectF m_rect;
private:
typedef QVector<SizeHandleRect*> Handles;
Handles m_handles;
int selection_handle_size = 4;
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void setState(SelectionHandleState st);
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
};
#endif // GRAPHICSRECTITEM_H
graphicsscene.h
#ifndef GRAPHICSRECTITEM_H
#define GRAPHICSRECTITEM_H
#include <QGraphicsItem>
#include "sizehandlerect.h"
class GraphicsRectItem : public QGraphicsItem
{
public:
GraphicsRectItem(const QRect & rect ,QGraphicsItem * parent);
QRectF boundingRect() const;
virtual void resizeTo(SizeHandleRect::Direction dir, const QPointF & point );
void move(const QPointF & point);
virtual Qt::CursorShape getCursor(SizeHandleRect::Direction dir );
SizeHandleRect::Direction hitTest( const QPointF & point ) const;
virtual QRectF rect() const;
virtual void updateGeometry();
QRectF m_rect;
private:
typedef QVector<SizeHandleRect*> Handles;
Handles m_handles;
int selection_handle_size = 4;
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void setState(SelectionHandleState st);
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
};
#endif // GRAPHICSRECTITEM_H
graphicsview.h
#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H
#include <QGraphicsView>
#include <QKeyEvent>
#include <QWheelEvent>
class GraphicsView : public QGraphicsView
{
Q_OBJECT
public:
GraphicsView(QWidget *parent = 0);
protected:
void keyPressEvent(QKeyEvent *event);
void wheelEvent(QWheelEvent *event);
};
#endif // GRAPHICSVIEW_H
sizehandlerec.h
#ifndef SIZEHANDLERECT_H
#define SIZEHANDLERECT_H
#include <QGraphicsRectItem>
enum SelectionHandleState { SelectionHandleOff, SelectionHandleInactive, SelectionHandleActive };
class SizeHandleRect : public QGraphicsRectItem
{
public:
enum Direction { LeftTop , Top, RightTop, Right, RightBottom, Bottom, LeftBottom, Left , Center, None};
SizeHandleRect(QGraphicsItem* parent , QRectF rect, Direction dir);
Direction dir() const;
bool hitTest( const QPointF & point );
void move(qreal x, qreal y );
void setState(SelectionHandleState st);
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
private:
const Direction m_dir;
SelectionHandleState m_state;
};
#endif // SIZEHANDLERECT_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "GraphicsRect/graphicsscene.h"
#include "GraphicsRect/graphicsview.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_createRect_clicked();
void on_pushButton_getRect_clicked();
void on_pushButton_addPix_clicked();
private:
Ui::MainWindow *ui;
GraphicsScene *scene = NULL;
};
#endif // MAINWINDOW_H
下面是资源文件
graphicsrectitem.cpp
#include "graphicsrectitem.h"
#include <QPen>
#include <QPainter>
#include <QDebug>
GraphicsRectItem::GraphicsRectItem(const QRect &rect, QGraphicsItem *parent) :
QGraphicsItem(parent)
{
m_rect = rect;
m_handles.reserve(SizeHandleRect::None);
for (int i = SizeHandleRect::LeftTop; i <= SizeHandleRect::Left; ++i) {
SizeHandleRect *shr = new SizeHandleRect(this, QRectF(0,0,1,1), static_cast<SizeHandleRect::Direction>(i));
m_handles.push_back(shr);
}
updateGeometry();
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
this->setAcceptHoverEvents(true);
}
void GraphicsRectItem::resizeTo(SizeHandleRect::Direction dir, const QPointF &point)
{
QPointF local = mapFromScene(point);
QString dirName;
QRect delta =m_rect.toRect();
switch (dir) {
case SizeHandleRect::LeftTop:
delta.setTopLeft(local.toPoint());
break;
case SizeHandleRect::Top:
dirName = "Top";
delta.setTop(local.y());
break;
case SizeHandleRect::RightTop:
dirName = "RightTop";
delta.setTopRight(local.toPoint());
break;
case SizeHandleRect::Left:
dirName = "Left";
delta.setLeft(local.x());
break;
case SizeHandleRect::Right:
dirName = "Rigth";
delta.setRight(local.x());
break;
case SizeHandleRect::LeftBottom:
dirName = "LeftBottom";
delta.setBottomLeft(local.toPoint());
break;
case SizeHandleRect::Bottom:
dirName = "Bottom";
delta.setBottom(local.y());
break;
case SizeHandleRect::RightBottom:
dirName = "RightBottom";
delta.setBottomRight(local.toPoint());
break;
default:
break;
}
prepareGeometryChange();
// if(m_isSquare)
// {
// delta.setHeight(delta.width());
// }
m_rect =delta;
updateGeometry();
}
void GraphicsRectItem::move(const QPointF &point)
{
QPointF local = mapFromScene(point);
QRectF delta = QRectF(local, m_rect.size());
prepareGeometryChange();
m_rect =delta;
updateGeometry();
}
Qt::CursorShape GraphicsRectItem::getCursor(SizeHandleRect::Direction dir)
{
switch (dir) {
case SizeHandleRect::Right:
return Qt::SizeHorCursor;
case SizeHandleRect::RightTop:
return Qt::SizeBDiagCursor;
case SizeHandleRect::RightBottom:
return Qt::SizeFDiagCursor;
case SizeHandleRect::LeftBottom:
return Qt::SizeBDiagCursor;
case SizeHandleRect::Bottom:
return Qt::SizeVerCursor;
case SizeHandleRect::LeftTop:
return Qt::SizeFDiagCursor;
case SizeHandleRect::Left:
return Qt::SizeHorCursor;
case SizeHandleRect::Top:
return Qt::SizeVerCursor;
default:
break;
}
return Qt::ArrowCursor;
}
SizeHandleRect::Direction GraphicsRectItem::hitTest(const QPointF &point) const
{
const Handles::const_iterator hend = m_handles.end();
for (Handles::const_iterator it = m_handles.begin(); it != hend; ++it)
{
if ((*it)->hitTest(point) ){
return (*it)->dir();
}
}
return SizeHandleRect::None;
}
void GraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QPen pen =painter->pen();
pen.setWidth(4);
pen.setColor(QColor(255, 0, 0));
painter->setPen(pen);
painter->drawRect(rect());
}
void GraphicsRectItem::updateGeometry()
{
const QRectF &rect = this->boundingRect();
const Handles::iterator hend = m_handles.end();
for (Handles::iterator it = m_handles.begin(); it != hend; ++it) {
SizeHandleRect *hndl = *it;;
switch (hndl->dir()) {
case SizeHandleRect::LeftTop:
hndl->move(rect.x() - selection_handle_size / 2, rect.y() - selection_handle_size / 2);
break;
case SizeHandleRect::Top:
hndl->move(rect.x() + rect.width() / 2 - selection_handle_size / 2, rect.y() - selection_handle_size / 2);
break;
case SizeHandleRect::RightTop:
hndl->move(rect.x() + rect.width() - selection_handle_size / 2, rect.y() - selection_handle_size / 2);
break;
case SizeHandleRect::Right:
hndl->move(rect.x() + rect.width() - selection_handle_size / 2, rect.y() + rect.height() / 2 - selection_handle_size / 2);
break;
case SizeHandleRect::RightBottom:
hndl->move(rect.x() + rect.width() - selection_handle_size / 2, rect.y() + rect.height() - selection_handle_size / 2);
break;
case SizeHandleRect::Bottom:
hndl->move(rect.x() + rect.width() / 2 - selection_handle_size / 2, rect.y() + rect.height() - selection_handle_size / 2);
break;
case SizeHandleRect::LeftBottom:
hndl->move(rect.x() - selection_handle_size / 2, rect.y() + rect.height() - selection_handle_size / 2);
break;
case SizeHandleRect::Left:
hndl->move(rect.x() - selection_handle_size / 2, rect.y() + rect.height() / 2 - selection_handle_size / 2);
break;
case SizeHandleRect::Center:
hndl->move(rect.center().x() - selection_handle_size / 2 , rect.center().y() - selection_handle_size / 2);
break;
default:
break;
}
}
}
QRectF GraphicsRectItem::rect() const
{
return QRectF(QPointF(m_rect.left(),m_rect.top()),
QPointF(m_rect.right(), m_rect.bottom()));
}
void GraphicsRectItem::setState(SelectionHandleState st)
{
const Handles::iterator hend = m_handles.end();
for (Handles::iterator it = m_handles.begin(); it != hend; ++it)
(*it)->setState(st);
}
QVariant GraphicsRectItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if ( change == QGraphicsItem::ItemSelectedHasChanged ) {
qDebug()<<" Item Selected : " << value.toString();
setState(value.toBool() ? SelectionHandleActive : SelectionHandleOff);
}else if ( change == QGraphicsItem::ItemRotationHasChanged ){
qDebug()<<"Item Rotation Changed:" << value.toString();
}else if ( change == QGraphicsItem::ItemTransformOriginPointHasChanged ){
qDebug()<<"ItemTransformOriginPointHasChanged:" << value.toPointF();
}
return value;
}
QRectF GraphicsRectItem::boundingRect() const
{
return rect();
}
graphicsscene.cpp
#include "graphicsscene.h"
#include <QGraphicsView>
#include <QDebug>
enum SelectMode
{
none,
netSelect,
move, //移动
size, //改变大小
rotate //反转
};
SelectMode selectMode = none;
SizeHandleRect::Direction nDragHandle = SizeHandleRect::None;
GraphicsScene::GraphicsScene()
{
}
void GraphicsScene::creatRect()
{
// if(m_RectItem){
// return;
// }
this->clearSelection();
m_RectItem = new GraphicsRectItem(QRect(0, 0, 200, 100), NULL);
this->addItem(m_RectItem);
m_RectItem->setSelected(true);
this->update();
}
void GraphicsScene::SetBackGroundImage(QPixmap pix, int width, int height)
{
this->clear();
QGraphicsPixmapItem* _backGroundItem= this->addPixmap(pix);
qreal scale = 0.0;
if((double)width/height > (double)pix.width()/pix.height()){
scale = (double)height/pix.height();
} else{
scale = (double)width/pix.width();
}
_backGroundItem->setScale(scale);
// _backGroundItem->setPos(0,0);
}
void GraphicsScene::setCursor(const QCursor &cursor)
{
QList<QGraphicsView*> views = this->views();
if ( views.count() > 0 ){
QGraphicsView * view = views.first();
view->setCursor(cursor);
}
}
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QList<QGraphicsItem *> items = this->selectedItems();
GraphicsRectItem *item = 0;
if ( items.count() == 1 )
{
item = qgraphicsitem_cast<GraphicsRectItem*>(items.first());
nDragHandle = item->hitTest(event->scenePos());
if ( nDragHandle !=SizeHandleRect::None)
selectMode = size;
else
selectMode = move;
}
if(selectMode == move || selectMode == none){
QGraphicsScene::mousePressEvent(event);
}
}
void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QList<QGraphicsItem *> items = this->selectedItems();
if(items.count() == 1){
GraphicsRectItem *item = qgraphicsitem_cast<GraphicsRectItem*>(items.first());
if ( nDragHandle != SizeHandleRect::None && selectMode == size ){
item->resizeTo(nDragHandle,event->scenePos());
}
else if(nDragHandle == SizeHandleRect::None && selectMode == none ){
SizeHandleRect::Direction handle = item->hitTest(event->scenePos());
if ( handle != SizeHandleRect::None){
setCursor(item->getCursor(handle));
}else{
setCursor(Qt::ArrowCursor);
}
}
else if(nDragHandle == SizeHandleRect::None && selectMode == move ){
item->move(event->scenePos());
}
}
this->update();
}
void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
setCursor(Qt::ArrowCursor);
selectMode = none;
nDragHandle = SizeHandleRect::None;
QGraphicsScene::mouseReleaseEvent(event);
}
graphicsview.cpp
#include "graphicsview.h"
GraphicsView::GraphicsView(QWidget *parent) :
QGraphicsView(parent)
{
this->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
this->setResizeAnchor(QGraphicsView::AnchorUnderMouse);
}
void GraphicsView::keyPressEvent(QKeyEvent *event)
{
switch (event->key())
{
case Qt::Key_Plus :
scale(1.2, 1.2);
break;
case Qt::Key_Minus :
scale(1 / 1.2, 1 / 1.2);
break;
case Qt::Key_Right :
rotate(30);
break;
}
QGraphicsView::keyPressEvent(event);
}
void GraphicsView::wheelEvent(QWheelEvent *event)
{
// 滚轮的滚动量
QPoint scrollAmount = event->angleDelta();
// 正值表示滚轮远离使用者(放大),负值表示朝向使用者(缩小)
scrollAmount.y() > 0 ? scale(1.2, 1.2) : scale(1 / 1.2, 1 / 1.2);
}
sizehandlerect.cpp
#include "sizehandlerect.h"
#include <QPainter>
SizeHandleRect::SizeHandleRect(QGraphicsItem *parent, QRectF rect, Direction dir) :
QGraphicsRectItem(rect, parent),
m_dir(dir),
m_state(SelectionHandleOff)
{
setParentItem(parent);
hide();
}
SizeHandleRect::Direction SizeHandleRect::dir() const
{
return m_dir;
}
bool SizeHandleRect::hitTest(const QPointF &point)
{
QPointF pt = mapFromScene(point);
return rect().contains(pt);
}
void SizeHandleRect::move(qreal x, qreal y)
{
setPos(x,y);
}
void SizeHandleRect::setState(SelectionHandleState st)
{
if (st == m_state)
return;
switch (st) {
case SelectionHandleOff:
hide();
break;
case SelectionHandleInactive:
case SelectionHandleActive:
show();
break;
}
m_state = st;
}
void SizeHandleRect::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QColor c = QColor("limegreen");
// c.setAlpha(200);
painter->setPen(Qt::NoPen);
painter->setBrush(QBrush(c));
painter->drawRect(rect());
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new GraphicsScene();
ui->graphicsView->setScene(scene);
scene->addItem(new GraphicsRectItem(QRect(-1, -1, 3, 3), NULL));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_createRect_clicked()
{
scene->creatRect();
}
void MainWindow::on_pushButton_getRect_clicked()
{
if(scene->m_RectItem){
// QPoint point = scene->m_RectItem->m_rect.topLeft();
QRect rect = scene->m_RectItem->rect().toRect();
ui->lineEdit->setText("x:" + QString::number(rect.topLeft().x()) + " y:" + QString::number(rect.topLeft().y())
+ " w:" + QString::number(rect.width()) + " h:" + QString::number(rect.height()));
}
}
void MainWindow::on_pushButton_addPix_clicked()
{
QPixmap pix("D:/imageprocess/111111111GraphicsRectDemo/img.bmp");
// QPixmap pix("img.jpg");
scene->SetBackGroundImage(pix, ui->graphicsView->width(), ui->graphicsView->height());
}