实现工具栏中‘放大’、‘缩小’和‘自适应’三个action的操作响应,实现场景的拖动操作(鼠标中键)

This commit is contained in:
duanshengchao 2024-08-23 15:28:59 +08:00
parent 88eb1b69dd
commit d9faf99ab5
8 changed files with 166 additions and 59 deletions

View File

@ -11,6 +11,11 @@ public:
explicit DesignerView(QWidget *parent = 0);
virtual ~DesignerView();
//视图操作-外部调用
void zoomIn();
void zoomOut();
void zoomFit();
protected:
virtual void contextMenuEvent(QContextMenuEvent*) override;
virtual void mousePressEvent(QMouseEvent*) override;
@ -20,14 +25,16 @@ protected:
private:
void initialize();
//缩放相关
//视图操作相关
void zoom(const QPointF&, double);
bool zoomLimit(double&);
double getScaleFactor();
void translate(const QPointF&);
private:
bool m_bMousePress;
double m_dZoomVaule;
bool m_bMousePress;
double m_dScale;
QPointF m_ptLatstMouse_view; //鼠标最后按下在view中的位置
};
#endif

View File

@ -22,6 +22,10 @@ public:
QGraphicsScene* getQGraphicsScene();
DesignerScene* getDesignerScene();
void grahpicsViewZoomIn();
void grahpicsViewZoomOut();
void grahpicsViewZoomFit();
public slots:
void onSignal_addGraphicsItem(GraphicsItemType&);

View File

@ -3,8 +3,8 @@
#include <QGraphicsItem>
const double g_dGriaphicsScene_Width = 5000;
const double g_dGriaphicsScene_Height = 5000;
const double g_dGriaphicsScene_Width = 1200;
const double g_dGriaphicsScene_Height = 900;
enum GraphicsItemType
{

View File

@ -29,12 +29,16 @@ public:
protected:
virtual void closeEvent(QCloseEvent* event) override;
virtual void changeEvent(QEvent* event) override;
private:
void initializeDockUi();
void initializeAction();
private slots:
void onAction_zoomIn();
void onAction_zoomOut();
void onAction_zoomFit();
void onSignal_addItem(QGraphicsItem*);
void onSignal_deleteItem();

View File

@ -8,7 +8,7 @@ DesignerView::DesignerView(QWidget *parent)
: QGraphicsView(parent)
{
m_bMousePress = false;
m_dZoomVaule = 1.0;
m_dScale = 1.0;
initialize();
}
DesignerView::~DesignerView()
@ -19,8 +19,8 @@ DesignerView::~DesignerView()
void DesignerView::initialize()
{
//去掉QGraphicsView自带滚动条
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
//setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
//setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
//设置背景
setStyleSheet("background-image: url(:/images/checkerboard.png);\
padding: 0px; \
@ -33,18 +33,77 @@ void DesignerView::initialize()
centerOn(0, 0);
}
void DesignerView::contextMenuEvent(QContextMenuEvent* event)
{
Q_UNUSED(event);
m_bMousePress = false;
}
void DesignerView::mousePressEvent(QMouseEvent* event)
{
QGraphicsItem* item = scene()->itemAt(mapToScene(event->pos()), transform());
if (event->button() == Qt::MiddleButton /*&& !item*/) //在空白处按住中键进行拖动
{
m_bMousePress = true;
setCursor(Qt::ClosedHandCursor);
m_ptLatstMouse_view = event->pos();
}
else
QGraphicsView::mousePressEvent(event);
}
void DesignerView::mouseMoveEvent(QMouseEvent* event)
{
if(m_bMousePress)
{
QPointF mouseMoveLength = event->pos() - m_ptLatstMouse_view.toPoint();
translate(mouseMoveLength);
m_ptLatstMouse_view = event->pos();
}
else
QGraphicsView::mouseMoveEvent(event);
}
void DesignerView::mouseReleaseEvent(QMouseEvent* event)
{
if (event->button() == Qt::MiddleButton) //按住中键进行拖动
{
m_bMousePress = false;
setCursor(Qt::ArrowCursor);
}
else
QGraphicsView::mouseReleaseEvent(event);
}
void DesignerView::wheelEvent(QWheelEvent* event) //滚轮进行放大缩小
{
QPointF mousePos = event->position();
double angleDeltaY = event->angleDelta().y();
double zoomFactor = qPow(1.0015, angleDeltaY); //可以实现更平滑的缩放
zoom(mousePos, zoomFactor);
//注意不要调用基类的滚轮函数,否则滚轮事件会映射到滚动条操作
//QGraphicsView::wheelEvent(event);
}
double DesignerView::getScaleFactor()
{
//QTransform为一个3*3的矩阵m11和m22元素分别为水平和垂直的缩放值
return this->transform().m11();
}
bool DesignerView::zoomLimit(double& value)
{
m_dZoomVaule *= value;
if(m_dZoomVaule >= MAX_ZoomValue)
m_dScale *= value;
if(m_dScale >= MAX_ZoomValue)
{
m_dZoomVaule = MAX_ZoomValue;
value = m_dZoomVaule / getScaleFactor();
m_dScale = MAX_ZoomValue;
value = m_dScale / getScaleFactor();
}
else if(m_dZoomVaule <= MIN_ZoomValue)
else if(m_dScale <= MIN_ZoomValue)
{
m_dZoomVaule = MIN_ZoomValue;
value = m_dZoomVaule / getScaleFactor();
m_dScale = MIN_ZoomValue;
value = m_dScale / getScaleFactor();
}
if(qFabs(value - 1) < 0.01) //缩放因子近似为1
@ -73,55 +132,49 @@ void DesignerView::zoom(const QPointF& mousePos, double zoomFactor)
setTransformationAnchor(lastAnchor);
}
double DesignerView::getScaleFactor()
void DesignerView::zoomIn()
{
//QTransform为一个3*3的矩阵m11和m22元素分别为水平和垂直的缩放值
return this->transform().m11();
//以view的中心点作为放大中心
double dWidth_View = viewport()->width();
double dHeight_View = viewport()->height();
QPoint pt(dWidth_View * 0.5, dHeight_View * 0.5);
zoom(pt, 1.1);
}
void DesignerView::contextMenuEvent(QContextMenuEvent* event)
void DesignerView::zoomOut()
{
Q_UNUSED(event);
m_bMousePress = false;
//以view的中心点作为缩小中心
double dWidth_View = viewport()->width();
double dHeight_View = viewport()->height();
QPoint pt(dWidth_View * 0.5, dHeight_View * 0.5);
zoom(pt, 0.9);
}
void DesignerView::mousePressEvent(QMouseEvent* event)
void DesignerView::zoomFit()
{
if (event->button() == Qt::MiddleButton) //按住中键进行拖动
{
m_bMousePress = true;
}
else
QGraphicsView::mousePressEvent(event);
resetTransform();
double dWidth_View = viewport()->width();
double dHeight_View = viewport()->height();
double dWidth_Scene = scene()->sceneRect().width();
double dHeight_Scene = scene()->sceneRect().height();
double dWidthScale = dWidth_View / dWidth_Scene;
double dHeightScale = dHeight_View / dHeight_Scene;
m_dScale = qMin(dWidthScale, dHeightScale);
QTransform trans = transform();
trans.scale(m_dScale, m_dScale);
setTransform(trans);
centerOn(0, 0);
}
void DesignerView::mouseMoveEvent(QMouseEvent* event)
void DesignerView::translate(const QPointF& delta)
{
if(m_bMousePress)
{
}
else
QGraphicsView::mouseMoveEvent(event);
}
void DesignerView::mouseReleaseEvent(QMouseEvent* event)
{
if (event->button() == Qt::MiddleButton) //按住中键进行拖动
{
m_bMousePress = false;
}
else
QGraphicsView::mouseReleaseEvent(event);
}
void DesignerView::wheelEvent(QWheelEvent* event) //滚轮进行放大缩小
{
QPointF mousePos = event->position();
double angleDeltaY = event->angleDelta().y();
double zoomFactor = qPow(1.0015, angleDeltaY); //可以实现更平滑的缩放
zoom(mousePos, zoomFactor);
//注意不要调用基类的滚轮函数,否则滚轮事件会映射到滚动条操作
//QGraphicsView::wheelEvent(event);
ViewportAnchor lastAnchor = this->transformationAnchor();
setTransformationAnchor(QGraphicsView::NoAnchor);
QTransform trans = transform();
trans.translate(delta.x(), delta.y());
setTransform(trans);
setTransformationAnchor(lastAnchor);
}

View File

@ -36,6 +36,21 @@ DesignerScene* DrawingPanel::getDesignerScene()
return m_pGraphicsScene;
}
void DrawingPanel::grahpicsViewZoomIn()
{
m_pGraphicsView->zoomIn();
}
void DrawingPanel::grahpicsViewZoomOut()
{
m_pGraphicsView->zoomOut();
}
void DrawingPanel::grahpicsViewZoomFit()
{
m_pGraphicsView->zoomFit();
}
void DrawingPanel::onSignal_addGraphicsItem(GraphicsItemType& itemType)
{
if(SelectorManager::getInstance())

View File

@ -50,6 +50,12 @@ void CMainWindow::closeEvent(QCloseEvent* event)
QMainWindow::closeEvent(event);
}
void CMainWindow::changeEvent(QEvent* event)
{
if (event->type() == QEvent::WindowStateChange)
m_pDrawingPanel->grahpicsViewZoomFit();
}
void CMainWindow::initializeDockUi()
{
CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true);
@ -106,6 +112,24 @@ void CMainWindow::initializeAction()
ui->actionDelete->setShortcut(QKeySequence::Delete);
connect(ui->actionDelete, SIGNAL(triggered()), this, SLOT(onSignal_deleteItem()));
connect(ui->actionZoomIn, SIGNAL(triggered()), this, SLOT(onAction_zoomIn()));
connect(ui->actionZoomOut, SIGNAL(triggered()), this, SLOT(onAction_zoomOut()));
connect(ui->actionZoomFit, SIGNAL(triggered()), this, SLOT(onAction_zoomFit()));
}
void CMainWindow::onAction_zoomIn()
{
m_pDrawingPanel->grahpicsViewZoomIn();
}
void CMainWindow::onAction_zoomOut()
{
m_pDrawingPanel->grahpicsViewZoomOut();
}
void CMainWindow::onAction_zoomFit()
{
m_pDrawingPanel->grahpicsViewZoomFit();
}
void CMainWindow::onSignal_addItem(QGraphicsItem* item)

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>756</height>
<width>1612</width>
<height>1016</height>
</rect>
</property>
<property name="windowTitle">
@ -19,7 +19,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<width>1612</width>
<height>33</height>
</rect>
</property>