zoukankan      html  css  js  c++  java
  • Qt QGraphics类应用——图片移动+选点缩放+控制移动区域

    记录:本博客用来记录学习,引用博客https://blog.csdn.net/weixin_43935474/article/details/89327314

    功能:

      1、图片可以使用鼠标进行拖动

      2、图片可以在鼠标位置放大缩小

      3、图片移动的区域固定

    需求:

      图片一张

    成品:

     

    代码:

    ImageWidget.h

     1 #ifndef IMAGEWIDGET_H
     2 #define IMAGEWIDGET_H
     3 
     4 #include <QWidget>
     5 #include <QtGui>
     6 #include <QPixmap>
     7 #include <QPainter>
     8 #include <QRectF>
     9 #include <QMouseEvent>
    10 #include <QPointF>
    11 #include <QDragEnterEvent>
    12 #include <QGraphicsSceneWheelEvent>
    13 #include <QGraphicsItem>
    14 
    15 enum Enum_ZoomState{
    16     NO_STATE,
    17     RESET,
    18     ZOOM_IN,
    19     ZOOM_OUT
    20 };
    21 // class ImageWidget :public QObject, QGraphicsItem
    22 class ImageWidget :public QGraphicsItem
    23 {
    24     //Q_OBJECT
    25 public:
    26     ImageWidget(QPixmap *pixmap);
    27     QRectF  boundingRect() const;
    28     void    paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    29     void    wheelEvent(QGraphicsSceneWheelEvent *event);
    30     void    ResetItemPos();
    31     //QVariant itemChange(GraphicsItemChange change, const QVariant &value);
    32     void    mousePressEvent(QGraphicsSceneMouseEvent *event);
    33     void    mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    34     void    mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    35     qreal   getScaleValue() const;
    36     void    setQGraphicsViewWH(int nwidth,int nheight);
    37 private:
    38     qreal       m_scaleValue;
    39     qreal       m_scaleDafault;
    40     QPixmap     m_pix;
    41     int         m_zoomState;
    42     bool        m_isMove;
    43     QPointF     m_startPos;
    44 };
    45 #endif // IMAGEWIDGET_H

    ImageWidget.cpp

    #include "imagewidget.h"
    #include <QDebug>
    #include <QGraphicsSceneMouseEvent>
    #include <QPointF>
    #include <QGraphicsSceneDragDropEvent>
    #include <QDrag>
    #include <math.h>
    
    ImageWidget::ImageWidget(QPixmap *pixmap)
    {
        m_pix = *pixmap;
        //If enabled is true, this item will accept hover events; otherwise, it will ignore them. By default, items do not accept hover events.
        setAcceptDrops(true);//true接收悬停事件
        m_scaleValue = 0;
        m_scaleDafault = 0;
        m_isMove = false;
    }
    
    QRectF ImageWidget::boundingRect() const
    {
        return QRectF(-m_pix.width() / 2, -m_pix.height() / 2,
                      m_pix.width(), m_pix.height());
    }
    
    void ImageWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
                        QWidget *)
    {
        painter->drawPixmap(-m_pix.width() / 2, -m_pix.height() / 2, m_pix);
    }
    
    void ImageWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        if(event->button()== Qt::LeftButton)
        {
            m_startPos = event->pos();//鼠标左击时,获取当前鼠标在图片中的坐标,
            m_isMove = true;//标记鼠标左键被按下
        }
        else if(event->button() == Qt::RightButton)
        {
            ResetItemPos();//右击鼠标重置大小
        }
    
    }
    
    void ImageWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        qreal x = m_pix.width()/4;
        qreal y = m_pix.height()/4;
    
            if(pos().x() <= (-x))
            {
                setPos(qreal(-x+1),pos().y());
                m_isMove = false;
            }
            if(pos().x() >= x)
            {
                setPos(QPointF(x-1,pos().y()));
                m_isMove = false;
            }
            if(pos().y() <= (-y))
            {
                setPos(pos().x(),qreal(-y+1));
                m_isMove = false;
            }
            if(pos().y() >= y)
            {
                setPos(pos().x(),qreal(y-1));
                m_isMove = false;
            }
        if(m_isMove)
        {
            QPointF point = (event->pos() - m_startPos)*m_scaleValue;
            moveBy(point.x(), point.y());
        }
        qDebug()<<"m_pix.width()/3="<<m_pix.width()/3;
        qDebug()<<"m_pix.height()/3="<<m_pix.height()/3;
        qDebug()<<"event->pos="<<event->pos();
        qDebug()<<"pos="<<pos();
    }
    
    void ImageWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
    {
        m_isMove = false;//标记鼠标左键已经抬起
    }
    
    
    void ImageWidget::wheelEvent(QGraphicsSceneWheelEvent *event)//鼠标滚轮事件
    {
        //选点缩放=缩放+移动
        if((event->delta() > 0)&&(m_scaleValue >= 50))//最大放大到原始图像的50倍
        {
            return;
        }
        else if((event->delta() < 0)&&(m_scaleValue <= m_scaleDafault))//图像缩小到自适应大小之后就不继续缩小
        {
            ResetItemPos();//重置图片大小和位置,使之自适应控件窗口大小
        }
        else
        {
            //①缩放
            qreal qrealOriginScale = m_scaleValue;
            if(event->delta() > 0)//鼠标滚轮向前滚动
            {
                m_scaleValue*=1.1;//每次放大10%
            }
            else
            {
                m_scaleValue*=0.9;//每次缩小10%
            }
            setScale(m_scaleValue);
            //②移动
            if(event->delta() > 0)
            {
                moveBy(-event->pos().x()*qrealOriginScale*0.1, -event->pos().y()*qrealOriginScale*0.1);//使图片缩放的效果看起来像是以鼠标所在点为中心进行缩放的
            }
            else
            {
                moveBy(event->pos().x()*qrealOriginScale*0.1, event->pos().y()*qrealOriginScale*0.1);//使图片缩放的效果看起来像是以鼠标所在点为中心进行缩放的
            }
        }
    }
    
    void ImageWidget::setQGraphicsViewWH(int nwidth, int nheight)//将主界面的控件QGraphicsView的width和height传进本类中,并根据图像的长宽和控件的长宽的比例来使图片缩放到适合控件的大小
    {
        int nImgWidth = m_pix.width();
        int nImgHeight = m_pix.height();
        qreal temp1 = nwidth*1.0/nImgWidth;
        qreal temp2 = nheight*1.0/nImgHeight;
        if(temp1>temp2)
        {
            m_scaleDafault = temp2;
        }
        else
        {
            m_scaleDafault = temp1;
        }
        setScale(m_scaleDafault);
        m_scaleValue = m_scaleDafault;
    }
    
    void ImageWidget::ResetItemPos()//重置图片位置
    {
        m_scaleValue = m_scaleDafault;//缩放比例回到一开始的自适应比例
        setScale(m_scaleDafault);//缩放到一开始的自适应大小
        setPos(0,0);
    }
    
    qreal ImageWidget::getScaleValue() const
    {
        return m_scaleValue;
    }
    

      

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include "imagewidget.h"
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
        
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        void            recvShowPicSignal(QImage image);//接收并显示图片的函数
    private:
        Ui::MainWindow *ui;
        ImageWidget    *m_Image;
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QGraphicsItem>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        recvShowPicSignal(QImage(QString::fromUtf8(":/image/但丁真魔人.jpg")));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::recvShowPicSignal(QImage image)
    {
    
        QPixmap ConvertPixmap=QPixmap::fromImage(image);
        int width = ui->ImageGraphic->width();//获取界面控件Graphics View的宽度
        int height = ui->ImageGraphic->height();//获取界面控件Graphics View的高度
    
        qDebug()<<"width="<<width<<" heigth="<<height<<" size="<< ui->ImageGraphic->size();
        //要用QGraphicsView就必须要有QGraphicsScene搭配着用
        QGraphicsScene  *qgraphicsScene = new QGraphicsScene;
        qgraphicsScene->setSceneRect(QRectF(-width/2,-height/2,width,height));
    
        qDebug()<<"width="<<width<<" height="<<height;
        //实例化类ImageWidget的对象m_Image,该类继承自QGraphicsItem,是自己写的类
        m_Image = new ImageWidget(&ConvertPixmap);
        //将界面控件Graphics View的width和height传进类m_Image中
        m_Image->setQGraphicsViewWH(width,height);
    
        //将QGraphicsItem类对象放进QGraphicsScene中
        qgraphicsScene->addItem(m_Image);
    
        //使视窗的大小固定在原始大小,不会随图片的放大而放大(默认状态下图片放大的时候视窗两边会自动出现滚动条,
        //并且视窗内的视野会变大),防止图片放大后重新缩小的时候视窗太大而不方便观察图片
        ui->ImageGraphic->setSceneRect(QRectF(-(width/2),-(height/2),width,height));//使视窗的大小固定在原始大小,不会随图片的放大而放大(默认状态下图片放大的时候视窗两边会自动出现滚动条,并且视窗内的视野会变大),防止图片放大后重新缩小的时候视窗太大而不方便观察图片
        //ui->ImageGraphic->setMinimumSize(width,height);
        ui->ImageGraphic->setScene(qgraphicsScene);
        ui->ImageGraphic->setFocus();//将界面的焦点设置到当前Graphics View控件
    
    }
    

      

  • 相关阅读:
    部署openstack的官网文档解读mysql的配置文件
    ubuntu14.04行更新软件包
    Ubuntu14.04上修改主机名
    ubuntu上修改root密码
    在ISE查看各个模块消耗的资源
    132
    Aurora 8B/10B、PCIe 2.0、SRIO 2.0三种协议比较
    NAND flash和NOR flash的区别详解
    FPGA三分频,五分频,奇数分频
    以太网之物理层
  • 原文地址:https://www.cnblogs.com/shuoguoleilei/p/12023664.html
Copyright © 2011-2022 走看看