1. 程式人生 > 其它 >Qt中檢視的縮放對應縮圖中矩形框的縮放

Qt中檢視的縮放對應縮圖中矩形框的縮放

技術標籤:Qt

本文實現的目的是:檢視縮放時,縮圖中的矩形框也進行縮放,而縮圖中的矩形區域為檢視中的可見區。
獲取檢視中滾動條的值,將其值與縮圖所在的小視窗對比,可通過繪圖求其比例,再按比例縮小。
首先提供主要的程式碼:

connect(view->verticalScrollBar(),&QScrollBar::valueChanged,this,&chunzhongForm::slot_VvalueChanged);
connect(view->horizontalScrollBar(),&QScrollBar::valueChanged,this
,&chunzhongForm::slot_HvalueChanged); void chunzhongForm::slot_VvalueChanged(int value) { if(value != 0 && dlg != NULL) { m_y = value; if(dlg->isVisible()) { emit signalSetDrawRectSize(); } } } void chunzhongForm::slot_HvalueChanged
(int value) { if(value != 0 && dlg != NULL) { m_x = value; if(dlg->isVisible()) { emit signalSetDrawRectSize(); } } } connect(this,&chunzhongForm::signalSetDrawRectSize,this,&chunzhongForm::slot_setViewRect); QSize GraphicsView::
viewportSizeHint() { return viewport()->size(); } void chunzhongForm::slot_setViewRect() { m_viewSize = view->viewportSizeHint();//獲取視口大小 int x = m_x / (m_viewSize.width() * m_scale)* SMALL_W; int y = m_y / (m_viewSize.height() * m_scale)* SMALL_H; int wid = SMALL_W / m_scale; int hei = SMALL_H / m_scale; outPut<<"小矩形座標及大小:"<<"("<<m_x<<" ,"<<m_y<<" ,"<<wid<<" ,"<<hei<<")";//換成qDebug()輸出 QRect rect(x,y,wid,hei); emit signalDrawRect(rect); } connect(this,&chunzhongForm::signalDrawRect,dlg,&BreviaryDlg::slot_setRectSize); //縮圖視窗類BreviaryDlg void BreviaryDlg::slot_setRectSize(QRect &rect) { m_rect = rect; scene->onSetPreviewRect(rect); } //縮圖中的自定義場景 void MyGraphicsScene::onSetPreviewRect(QRect rect) { m_rectSaved = rect; // 內縮幾個畫素,用矩形外邊框來標示viewport顯示區域 m_pRectItem->setRect(rect.x() - 2/*+ 5*/, rect.y() - 2/*+ 5*/, rect.width() - 4, rect.height() - 4);//設定圖形項矩形 }

下面貼出自定義場景類
MyGraphicsScene.h

#pragma once

//#include <vld.h>
#include <QGraphicsScene>

class MyGraphicsScene : public QGraphicsScene
{
    Q_OBJECT

public:
    MyGraphicsScene(QObject *parent = nullptr);

    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
    virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);

Q_SIGNALS:

    void previewRectMoved(QRect rect);

public Q_SLOTS:

    void onSetPreviewRect(QRect rect);

private:

    QGraphicsRectItem* m_pRectItem;
    QRect m_rectSaved;
    bool m_bRectClicked;
    QPoint m_ptRectRelated;     // 滑鼠點選時,相對於紅色矩形框的位置
};

MyGraphicsScene.cpp

#include "MyGraphicsScene.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsRectItem>
#include <QDebug>

MyGraphicsScene::MyGraphicsScene(QObject *parent)
    : QGraphicsScene(parent)
    , m_bRectClicked(false)
{
    m_pRectItem = new QGraphicsRectItem(0, 0, 0, 0);
    QPen penRectItem = QPen(QColor(255, 0, 0));
    penRectItem.setWidth(2);
    m_pRectItem->setPen(penRectItem);
    m_pRectItem->setZValue(1);
    addItem(m_pRectItem);
}

void MyGraphicsScene::onSetPreviewRect(QRect rect)
{
    m_rectSaved = rect;

    // 內縮幾個畫素,用矩形外邊框來標示viewport顯示區域
    m_pRectItem->setRect(rect.x() - 2/*+ 5*/, rect.y() - 2/*+ 5*/, rect.width() - 4, rect.height() - 4);
}

void MyGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    QGraphicsScene::mouseMoveEvent(mouseEvent);
    if (m_bRectClicked) {
        QPoint ptTopLeft = mouseEvent->scenePos().toPoint() - m_ptRectRelated;
        m_rectSaved.setTopLeft(ptTopLeft);
//        qDebug()<<"mouseMoveEvent";
        emit previewRectMoved(m_rectSaved);
    }
}

void MyGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    QGraphicsScene::mousePressEvent(mouseEvent);
    if (m_rectSaved.contains(mouseEvent->scenePos().x(), mouseEvent->scenePos().y())) {
        m_bRectClicked = true;
        m_ptRectRelated = mouseEvent->scenePos().toPoint() - m_rectSaved.topLeft();
    }
}

void MyGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    QGraphicsScene::mouseReleaseEvent(mouseEvent);
    m_bRectClicked = false;
}