Talking about the realization of a picture viewer

1. Ideas

    The project is based on Qt. The specific ideas are as follows:

    1. The picture viewer class inherits from QWidget.

    2. Use a QLabel to display the picture. The label is a child window of the image viewer, and its size changes with the size of the image.

    3. Save the original image and the zoom ratio of the image. Use the scaled function of QPixmap to get the scaled image object.


Second, the key code

   1. Member variables:

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


   2. Set the picture

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

   m_pixmap is used to save the original image, and the m_imgLabel setting is the same as the size of the image.


  3. Center the picture

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));
    }
}

According to the size of the label and the position of the center point of the window, the position of the label when it is centered is reversed.


4. Zoom

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();
}

In the mouse wheel event, the zoom ratio of the image is calculated first, and then the size of the image is calculated according to the zoom ratio. Then use scaled to scale, where Qt::KeepAspectRatio means to maintain the ratio of width and height. Qt::SmoothTransformation indicates that the image quality of smooth transformation and scaling is higher. Finally, keep the size of the label consistent with the size of the image.


5. Drag operation

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;
}
Controlled by overriding mouse down, move and up events. In the mouse press event, it is determined that the release is above the label. If it is, it is considered to be allowed to move and the mouse coordinates at this time are recorded. Then, in the mouse movement event, it is judged whether the movement is allowed. If it is allowed, the offset of the mouse is calculated and the position of the label is adjusted according to the offset. Finally in the mouse up event is set to disallow movement.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324838525&siteId=291194637