通过鼠标拖动来移动图片,并使用鼠标滚轮来缩放图片。
1、实现步骤:
1、移动图片:
使用QPoint记录图片的偏移量,当鼠标拖动时更新这个偏移量,在paintEvent( ) 中根据偏移量绘制图片。
2、缩放图片:
使用滚轮事件调整图片的缩放倍数,在paintEvent( ) 中重新绘制图片时应用缩放。
2、完整的解决方案:
1、ImageWidget.h
# ifndef IMAGEWIDGET_H
# define IMAGEWIDGET_H # include <QApplication>
# include <QWidget>
# include <QLabel>
# include <QPixmap>
# include <QMouseEvent>
# include <QWheelEvent>
# include <QPainter>
# include <QVBoxLayout>
# include <QDebug> class ImageWidget : public QWidget
{ Q_OBJECTpublic : ImageWidget ( QWidget * parent = nullptr ) ;
protected : void paintEvent ( QPaintEvent * event) override; void mousePressEvent ( QMouseEvent * event) override; void mouseMoveEvent ( QMouseEvent * event) override; void mouseReleaseEvent ( QMouseEvent * event) override; void wheelEvent ( QWheelEvent * event) override; private : QPixmap pixmap; QPoint lastMousePosition; QPoint offset; bool isDragging; double scaleFactor;
} ; # endif
2、ImageWidget.cpp
ImageWidget::ImageWidget( QWidget *parent) : QWidget( parent)
{ // 加载图片pixmap = QPixmap( R"(C:\Users\LiangQL\Desktop\开发者基础认证.jpg)" ) ; // 替换成你的图片路径scaleFactor = 1.0 ; // 初始缩放因子为1isDragging = false ; // 初始状态下不拖动offset = QPoint( 0 , 0 ) ; // 图片的初始偏移为( 0 , 0 )
}
// 重写paintEvent,用于绘制图片
void ImageWidget::paintEvent( QPaintEvent *event)
{ // 创建一个QPainter,用于绘制图片QPainter painter( this) ; painter.setRenderHint( QPainter::SmoothPixmapTransform) ; // 开启平滑缩放// 计算缩放后的图片尺寸QSize scaledSize = pixmap.size( ) * scaleFactor; // 绘制图片,应用缩放和偏移量painter.drawPixmap( offset, pixmap.scaled( scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)) ;
} // 鼠标按下事件
void ImageWidget::mousePressEvent( QMouseEvent *event)
{ if ( event-> button( ) == Qt::LeftButton) { isDragging = true ; // 开始拖动lastMousePosition = event-> pos( ) ; // 记录鼠标点击位置}
} // 鼠标移动事件
void ImageWidget::mouseMoveEvent( QMouseEvent *event)
{ if ( isDragging) { // 计算鼠标的移动距离QPoint delta = event-> pos( ) - lastMousePosition; // 更新图片的偏移量offset += delta; // 更新鼠标位置lastMousePosition = event-> pos( ) ; // 触发重新绘制update( ) ; }
} // 鼠标释放事件
void ImageWidget::mouseReleaseEvent( QMouseEvent *event)
{ if ( event-> button( ) == Qt::LeftButton) { isDragging = false ; // 结束拖动}
} // 滚轮事件,用于缩放图片
void ImageWidget::wheelEvent( QWheelEvent *event)
{ // 滚轮向上放大,向下缩小if ( event-> angleDelta( ) .y( ) > 0 ) { scaleFactor *= 1.1 ; // 放大} else { scaleFactor /= 1.1 ; // 缩小} // 限制缩放范围scaleFactor = qBound( 0.1 , scaleFactor, 10.0 ) ; // 更新显示update( ) ;
}
3、 调用main.cpp
int main( int argc, char *argv[ ] )
{ QApplication app( argc, argv) ; // 创建主窗口QWidget window; window.setFixedSize( 800 , 600 ) ; // 设置窗口大小// 创建图片控件(自定义的类)ImageWidget *imageWidget = new ImageWidget; // 使用布局管理器将图片控件放置在窗口中QVBoxLayout *layout = new QVBoxLayout( & window) ; layout-> addWidget( imageWidget) ; // 显示主窗口window.show( ) ; return app.exec( ) ;
}
3、详细解释:
1. paintEvent() 重绘图片:
paintEvent( ) 方法用于自定义控件的绘制。在这个方法中,我们使用QPainter对象来绘制图片。
pixmap.scaled( ) :使用pixmap.scaled( ) 方法来缩放图片,根据scaleFactor缩放图片并保持其宽高比。
painter.drawPixmap( offset, .. .) :在指定的偏移量位置绘制图片,offset表示图片在控件中的偏移。
2. 图片移动:
mousePressEvent( ) :当鼠标左键按下时,记录鼠标点击位置,并开始拖动图片(isDragging = true)。
mouseMoveEvent( ) :如果正在拖动图片(isDragging为true),则计算鼠标的移动距离,将图片的offset偏移量更新为原来的偏移量加上鼠标移动的距离。
mouseReleaseEvent( ) :当鼠标左键释放时,结束拖动(isDragging = false)。
3. 图片缩放:
wheelEvent( ) :处理鼠标滚轮事件。滚轮向上时,放大图片;滚轮向下时,缩小图片。
scaleFactor *= 1.1 :每次滚动时,缩放倍数按10%变化。
qBound( 0.1 , scaleFactor, 10.0 ) :限制缩放比例在0.1到10倍之间,防止图片缩得太小或放得太大。
4. 平滑缩放:
Qt::SmoothTransformation:使用平滑缩放算法,防止图片缩放后出现锯齿。
5. 偏移量的作用:
offset用于记录图片相对于窗口的偏移量,当鼠标拖动时,更新这个偏移量。
在paintEvent( ) 中,每次绘制时都使用这个偏移量来控制图片的位置。
运行效果:
拖动图片:按住鼠标左键并移动,可以看到图片在窗口内部移动。
缩放图片:滚动鼠标滚轮,图片会放大或缩小,同时保持宽高比。