一、思路
该项目基于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的位置。最后在鼠标弹起事件中设置不允许移动。