本文实现的目的是:视图缩放时,缩略图中的矩形框也进行缩放,而缩略图中的矩形区域为视图中的可见区。
获取视图中滚动条的值,将其值与缩略图所在的小窗口对比,可通过绘图求其比例,再按比例缩小。
首先提供主要的代码:
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;
}