浅谈一个图片查看器的实现

一、思路

    该项目基于Qt编写。具体思路如下:

    1.图片查看器类继承于QWidget。

    2.使用一个QLabel来显示图片。label是图片查看器的子窗口,它的大小随着图片的大小改变。

    3.保存原图以及图片的缩放的比例。使用QPixmap的scaled函数获得缩放后的图片对象。


二、关键代码

   1.成员变量:

C++
    QLabel*     m_imgLabel;  //用于显示图片
    QPixmap     m_pixmap;    //保存原图
    qreal       m_fScale;    //保存缩放比例
    bool        m_bMove;     //是否移动
    QPoint      m_ptPress;   //记录鼠标按下的位置


   2.设置图片

C++
void ImageViewer::setPixmap(const QPixmap& pixmap)
{
    m_pixmap = pixmap;
    m_imgLabel->setFixedSize(m_pixmap.size());
    m_imgLabel->setPixmap(m_pixmap);
    centerImgLabel();
}

   m_pixmap用于保存原图,m_imgLabel设置和图片的大小一致。


  3.使图片居中

C++
void ImageViewer::centerImgLabel()
{
    if(!m_pixmap.isNull())
    {
        QPoint centerPt = rect().center();
        int nWidth = m_imgLabel->width();
        int nHeight = m_imgLabel->height();
        m_imgLabel->move(centerPt + QPoint(-nWidth/2,-nHeight/2));
    }
}

根据label的大小以及窗口中心点位置反推label居中时的位置。


4.缩放

C++
void ImageViewer::wheelEvent(QWheelEvent *event)
{
    if(event->delta() > 0)
    {
       m_fScale *= 1.1;
    }
    else
    {
        m_fScale *= 0.9;
    }

    int nWidth = m_pixmap.width()*m_fScale;
    int nHeight = m_pixmap.height()*m_fScale;
    QPixmap scaledPixmap = m_pixmap.scaled(nWidth,nHeight,Qt::KeepAspectRatio,Qt::SmoothTransformation);
    m_imgLabel->setFixedSize(nWidth,nHeight);
    m_imgLabel->setPixmap(scaledPixmap);
    centerImgLabel();
}

在鼠标滚轮事件中,先计算图片缩放比例,然后根据缩放比例计算出图片的大小。接着使用scaled进行缩放,其中Qt::KeepAspectRatio表示保持宽高的比例。Qt::SmoothTransformation表示平滑变换缩放的图片质量较高。最后保持label的大小与图片大小一致。


5.拖动操作

C++
void ImageViewer::mousePressEvent(QMouseEvent *event)
{
    if(m_imgLabel->geometry().contains(event->pos()))
    {
        m_ptPress = event->pos();
        m_bMove = true;
    }
}

void ImageViewer::mouseMoveEvent(QMouseEvent *event)
{
    if(m_bMove){
        QPoint offsetPt = event->pos() - m_ptPress;
        m_imgLabel->move(m_imgLabel->pos() + offsetPt);
        m_ptPress = event->pos();
    }
}

void ImageViewer::mouseReleaseEvent(QMouseEvent *event)
{
    m_bMove = false;
}
通过重写鼠标按下、移动和弹起事件来控制。在鼠标按下事件中判定释放在label之上,如果是则认为允许移动并记录此时的鼠标坐标。接着在鼠标移动事件中判断是否允许移动,若允许则计算出鼠标的偏移量并根据偏移量调整label的位置。最后在鼠标弹起事件中设置不允许移动。

猜你喜欢

转载自blog.csdn.net/fanhenghui/article/details/80077345