setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
QGraphicsRectItem *pRectItem = new QGraphicsRectItem(QRectF(0,0,20,20));
pRectItem->setFlag(QGraphicsItem::ItemIsMovable,true);
mygraphicsview.h头文件
#ifndef MYGRAPHICSVIEW_H
#define MYGRAPHICSVIEW_H
#include
#include
class MyGraphicsView : public QGraphicsView
{
Q_OBJECT
public:
explicit MyGraphicsView(QWidget *parent = nullptr);
public:
qreal GetScaledValue() const //获取最新的放大倍数
{
return m_qrScaledNum;
}
void SetScaledDefaultValue()
{
this->m_qrScaledNum = 1;
}
protected:
void wheelEvent(QWheelEvent *ev); //重写graphicsView的滚轮事件
void mousePressEvent(QMouseEvent *ev); //重写鼠标按下事件
private:
qreal m_qrScaledNum; //视口缩放倍数
};
#endif // MYGRAPHICSVIEW_H
mygraphicsview.cpp源文件
#include "mygraphicsview.h"
#include
#include
#include
#define cout qDebug() << "["<< __FILE__ <<":" << __LINE__<<"]"
MyGraphicsView::MyGraphicsView(QWidget *parent) : QGraphicsView(parent)
{
this->setMouseTracking(true); //跟踪鼠标位置
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //隐藏水平条
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //隐藏竖条
m_qrScaledNum = 1; //初始化
}
//缩放
void MyGraphicsView::wheelEvent(QWheelEvent *ev)
{
//cout << "MyGraphicsView::wheelEvent ";
if(Qt::CTRL == ev->modifiers()) //键盘CTRL键
{
qreal qrTmp = 1.0;
if(ev->delta() > 0)
{
qrTmp = 1.2;
this->scale(qrTmp,qrTmp);
}
else
{
qrTmp = 1.0/1.2;
this->scale(qrTmp,qrTmp);
}
m_qrScaledNum *= qrTmp; //保存放大倍数
}
}
void MyGraphicsView::mousePressEvent(QMouseEvent *ev)
{
//视图坐标
QPoint nViewPoint = ev->pos();
cout << "nViewPoint = " << nViewPoint;
//场景坐标
QPointF fScenePoint = this->mapToScene(nViewPoint);
cout <<"fScenePoint = " << fScenePoint;
//图形项坐标
QGraphicsItem *pItem = this->scene()->itemAt(fScenePoint,QTransform());
if(0 != pItem)
{
QPointF fItemPoint = pItem->mapFromScene(fScenePoint); //获取图形项坐标
cout <<"fItemPoint = " << fItemPoint;
//cout <<" pItem->pos() = " << pItem->pos();
//pItem->setPos(0,0);
}
//默认的鼠标按下事件
QGraphicsView::mousePressEvent(ev);
}
mywidget.h头文件
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include
#include
#include
#include "mygraphicsview.h"
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MyWidget; }
QT_END_NAMESPACE
//显示模式
enum DisplayModeEnum
{
TOPLEFT = 0, //左上角顶点
XHorizontalMiddle, //X水平轴居中
YVerticalMiddle //Y垂直轴居中
};
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = nullptr);
~MyWidget();
private slots:
void on_pushBtnLoadImage_clicked();
void on_pushButton_clicked();
void ReleasedResourceSlot();
private:
qreal GetDefaultRatio(const QPixmap &pix,DisplayModeEnum &displayMode);
private:
Ui::MyWidget *ui;
QGraphicsScene *m_pScene; //场景
MyGraphicsView *m_pView; //视口
qreal m_qrShrinkedRatio; //视口缩放比例
qreal m_qrDefaultShrinkedRatio; //图形项默认缩放比例
int m_nViewWidth;
int m_nViewHeight;
};
#endif // MYWIDGET_H
mywidget.cpp源文件
#include "mywidget.h"
#include "ui_mywidget.h"
#include
#include
#include
#define cout qDebug() << "["<< __FILE__ <<":" << __LINE__<<"]"
#define VIEW_MAX_WIDTH 800 //视口最大宽度
#define VIEW_MAX_HEIGHT 600 //视口最大高度
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MyWidget)
{
ui->setupUi(this);
//创建视图
this->m_pView = new MyGraphicsView(this);
m_pView->resize(VIEW_MAX_WIDTH,VIEW_MAX_HEIGHT);
this->m_nViewWidth = m_pView->width();
this->m_nViewHeight = m_pView->height();
//创建场景
this->m_pScene = new QGraphicsScene(this);
//设置场景大小和左上角点坐标
this->m_pScene->setSceneRect(0,0,VIEW_MAX_WIDTH,VIEW_MAX_HEIGHT);
//窗口关闭释放资源
connect(this,&MyWidget::destroyed,this,&MyWidget::ReleasedResourceSlot);
}
MyWidget::~MyWidget()
{
if(nullptr != m_pView)
{
delete m_pView;
m_pView = nullptr;
}
if(nullptr != m_pScene)
{
delete m_pScene;
m_pScene = nullptr;
}
delete ui;
}
void MyWidget::on_pushBtnLoadImage_clicked()
{
//位置还原
on_pushButton_clicked();
//清空场景中的图形项
m_pScene->clear();
//加载图片
QString strFilePath = QFileDialog::getOpenFileName(this,tr("Load a Image!"),"C:/Users/zhengfei6/Desktop/testImage",tr("Images(*.png *.jpg *.bmp)"));
if(NULL == strFilePath)
{
cout << "FilePath is Null";
return;
}
//加载图片
QPixmap pix;
pix.load(strFilePath);
//获取缩放比例
DisplayModeEnum displayMode = DisplayModeEnum::TOPLEFT; //默认左上顶点显示
this->m_qrDefaultShrinkedRatio = GetDefaultRatio(pix,displayMode);
QGraphicsPixmapItem *pPixItem = new QGraphicsPixmapItem(pix);
pPixItem->setScale(1/this->m_qrDefaultShrinkedRatio);
pPixItem->setFlag(QGraphicsItem::ItemIsMovable,true);
QGraphicsRectItem *pRectItem = new QGraphicsRectItem(QRectF(0,0,20,20));
pRectItem->setFlag(QGraphicsItem::ItemIsMovable,true);
//图形项显示模式
switch (displayMode)
{
case TOPLEFT: //左上顶点显示
pPixItem->setPos(0,0);
break;
case XHorizontalMiddle: //水平居中显示
{
qreal qrXPos = ((qreal)VIEW_MAX_WIDTH-(qreal)pix.width()/m_qrDefaultShrinkedRatio)/2;
cout << "qrXPox = "<<qrXPos;
pPixItem->setPos(qrXPos,0);
}
break;
case YVerticalMiddle: //垂直居中显示
{
qreal qrYPos = ((qreal)VIEW_MAX_HEIGHT-(qreal)pPixItem->pixmap().height()/m_qrDefaultShrinkedRatio)/2;
cout << "qrYPos = " << qrYPos;
pPixItem->setPos(0,qrYPos);
}
break;
default:
break;
}
//添加图形项
m_pScene->addItem(pPixItem);
m_pScene->addItem(pRectItem);
//设置场景
m_pView->setScene(m_pScene);
m_pView->show();
}
qreal MyWidget::GetDefaultRatio(const QPixmap &pix,DisplayModeEnum &displayMode)
{
qreal dResRatio = 0;
qreal qrWidthRatio = (qreal)pix.width()/(qreal)VIEW_MAX_WIDTH;
qreal qrHeightRatio = (qreal)pix.height()/(qreal)VIEW_MAX_HEIGHT;
// cout << "qrWidthRatio = "<< qrWidthRatio;
qreal nMaxTmp = qMax(qrWidthRatio,qrHeightRatio); //取宽宽比和高高比的大者
// cout << "nMaxTmp = "<< nMaxTmp;
if(qrWidthRatio == nMaxTmp)
{
dResRatio = qrWidthRatio;
displayMode = DisplayModeEnum::YVerticalMiddle;
}
else
{
dResRatio = qrHeightRatio;
displayMode = DisplayModeEnum::XHorizontalMiddle;
}
//cout << "dResRatio = "<< dResRatio;
return dResRatio;
}
//视口还原为原来的缩放比例
void MyWidget::on_pushButton_clicked()
{
//获取view的缩放倍数
qreal qrTmp = m_pView->GetScaledValue();
m_pView->scale(1/qrTmp,1/qrTmp);
//还原后,更新下view中的放大倍数为1
m_pView->SetScaledDefaultValue();
//图形项还原位置
QList<QGraphicsItem*> pListItems = m_pScene->items();
foreach(QGraphicsItem* pItem , pListItems)
{
pItem->setPos(0,0);
}
}
void MyWidget::ReleasedResourceSlot()
{
#if 1
if(nullptr != m_pView)
{
delete m_pView;
m_pView = nullptr;
}
if(nullptr != m_pScene)
{
delete m_pScene;
m_pScene = nullptr;
}
#endif
cout <<"close the widget";
}
main.cpp源文件
#include "mywidget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWidget w;
w.show();
return a.exec();
}
《QT QGraphicsView 在鼠标点击处进行放大缩小》