博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
20.QT-Qpixmap实现图片鼠标缩放,鼠标拖动示例(详解)
阅读量:6714 次
发布时间:2019-06-25

本文共 6644 字,大约阅读时间需要 22 分钟。

通过 QPainter 绘画实现,以本地图片985*740为例

如下图所示:

效果如下所示:

 

 

实现原理

主要通过以下函数实现:

void QPainter::drawTiledPixmap ( int x, int y, int w int h const QPixmap & pixmap, int sx = 0, int sy = 0 );      //平铺显示pixmap      //x y w h :表示绘画区域      //sx  sy  :表示Qpixmap绘画起始位置

 

只要算出x y w h sx sy就能实现超出窗口不显示的效果

举个例子,如下图所示,居中显示1200*1200时:

当图片左偏移600时,也就是offset=-600时,则只能在窗口上显示一半的图片:

 

代码实现

widget.h:

#ifndef WIDGET_H#define WIDGET_H#include 
#include
class Widget : public QWidget{ Q_OBJECTprivate : QPixmap *pix; int action; //动作(放大,缩小,移动...) int pixW; //图片宽 int pixH; //图片高 QRect Paint; //绘画区域 float ratio; //比例 QPoint offset; //一次的图片偏移值 QPoint Alloffset; //总偏移 QLabel label; QPushButton BigButton; QPushButton LittleButton; QPushButton LiftButton; QPushButton RightButton; QPushButton UpButton; QPushButton DownButton; void AddComboItem(QComboBox* cmbo); bool event(QEvent * event); void wheelEvent(QWheelEvent* e); //鼠标滑轮事件private slots: void onUpClicked(); void onDownClicked(); void OnLiftClicked(); void OnRightClicked(); void onLittleClicked(); void onBigClicked(); void paintEvent(QPaintEvent *event);public: explicit Widget(); enum Type { None = 0, Amplification , Shrink, Lift, Right, Up, Down, Move };};#endif // WIDGET_H

widget.cpp:

 

#include "widget.h"Widget::Widget():    BigButton("放大",this),    LittleButton("缩小",this),    LiftButton("向左",this),    RightButton("向右",this),    UpButton("向上",this),    DownButton("向下",this),    Paint(10,10,810,810),    Alloffset(0,0),    label("100%",this){    ratio= 1.0;             //初始化图片缩放比例    action = Widget::None;    pixW = 985;            //设置图片尺寸为985*740    pixH = 740;    pix = new QPixmap;    pix->load(":/pic/img.jpg");    BigButton.setGeometry(822,10,60,25);    connect(&BigButton,SIGNAL(clicked()),this,SLOT(onBigClicked()));    LittleButton.setGeometry(822,40,60,25);    connect(&LittleButton,SIGNAL(clicked()),this,SLOT(onLittleClicked()));    LiftButton.setGeometry(822,70,60,25);    connect(&LiftButton,SIGNAL(clicked()),this,SLOT(OnLiftClicked()));    RightButton.setGeometry(822,100,60,25);    connect(&RightButton,SIGNAL(clicked()),this,SLOT(OnRightClicked()));    UpButton.setGeometry(822,130,60,25);    connect(&UpButton,SIGNAL(clicked()),this,SLOT(onUpClicked()));    DownButton.setGeometry(822,160,60,25);    connect(&DownButton,SIGNAL(clicked()),this,SLOT(onDownClicked()));    label.move(840,200);    resize(890,850);}bool Widget::event(QEvent * event){    static bool press=false;    static QPoint PreDot;    if(event->type() == QEvent::MouseButtonPress )    {           QMouseEvent *mouse = dynamic_cast
(event); //判断鼠标是否是左键按下,且鼠标位置是否在绘画区域 if(mouse->button()==Qt::LeftButton &&Paint.contains(mouse->pos())) { press=true; QApplication::setOverrideCursor(Qt::OpenHandCursor); //设置鼠标样式 PreDot = mouse->pos(); } }else if(event->type() == QEvent::MouseButtonRelease){ QMouseEvent *mouse = dynamic_cast
(event); //判断鼠标是否是左键释放,且之前是在绘画区域 if(mouse->button()==Qt::LeftButton && press ) { QApplication::setOverrideCursor(Qt::ArrowCursor); //改回鼠标样式 press=false; }} if(event->type() == QEvent::MouseMove) //移动图片 { if(press) { QMouseEvent *mouse = dynamic_cast
(event); offset.setX(mouse->x() - PreDot.x()); offset.setY(mouse->y() - PreDot.y()); PreDot = mouse->pos(); action = Widget::Move; this->update(); } }return QWidget::event(event);}void Widget::wheelEvent(QWheelEvent* event) //鼠标滑轮事件{ if (event->delta()>0) { //上滑,缩小 action=Widget::Shrink; this->update(); } else { //下滑,放大 action=Widget::Amplification; this->update(); } event->accept();}void Widget::paintEvent(QPaintEvent *event){ QPainter painter(this); int NowW = ratio *pixW; int NowH = ratio *pixH;if(action==Widget::Amplification) //缩小{ ratio-=0.1*ratio; if(ratio<0.018) ratio = 0.01; /*显示比例*/ QString str; str.sprintf("%.0f%",ratio*100); label.setText(str) ;}else if(action==Widget::Shrink) //放大{ ratio+=0.1*ratio; if(ratio>4.5) ratio = 5.000; /*显示比例*/ QString str; str.sprintf("%.0f%",ratio*100); label.setText(str);}if(action==Widget::Amplification || action==Widget::Shrink) //更新图片{ NowW = ratio *pixW; NowH = ratio *pixH; pix->load(":/pic/img.jpg"); //重新装载,因为之前的图片已经被缩放过 *pix = pix->scaled(NowW, NowH,Qt::KeepAspectRatio); action=Widget::None;}if(action==Widget::Move) //移动{ int offsetx=Alloffset.x()+offset.x(); Alloffset.setX(offsetx); int offsety=Alloffset.y()+offset.y(); Alloffset.setY(offsety); action=Widget::None;}if(abs(Alloffset.x())>=(Paint.width()/2 + NowW/2 -10)) //限制X偏移值{ if(Alloffset.x()>0) Alloffset.setX(Paint.width()/2 + NowW/2 -10); else Alloffset.setX(-Paint.width()/2 + -NowW/2 +10);}if(abs(Alloffset.y())>=(Paint.height()/2 + NowH/2 -10)) //限制Y偏移值{ if(Alloffset.y()>0) Alloffset.setY(Paint.height()/2 + NowH/2 -10); else Alloffset.setY(-Paint.height()/2 + -NowH/2 +10);}int x = Paint.width()/2 + Alloffset.x() -NowW/2;if(x<0) x=0;int y = Paint.height()/2 + Alloffset.y() -NowH/2;if(y<0) y=0;int sx = NowW/2 - Paint.width()/2 - Alloffset.x();if(sx<0) sx=0;int sy = NowH/2 - Paint.height()/2 - Alloffset.y();if(sy<0) sy=0;int w =(NowW - sx)>Paint.width()? Paint.width() : (NowW - sx);if(w>(Paint.width()-x)) w = Paint.width()-x;int h =(NowH - sy)>Paint.height()? Paint.height() : (NowH - sy);if(h>(Paint.height()-y)) h = Paint.height()-y; painter.drawRect(Paint.x()-1,Paint.y()-1,Paint.width()+1,Paint.height()+1); //画框 painter.drawTiledPixmap(x+Paint.x(),y+Paint.y(),w,h,*pix,sx,sy); //绘画图形}void Widget::onLittleClicked(){ action=Widget::Amplification; this->update();}void Widget::onBigClicked(){ action=Widget::Shrink; this->update();}void Widget::onUpClicked(){ action=Widget::Move; offset.setX(0); offset.setY(-20); this->update();}void Widget::onDownClicked(){ action=Widget::Move; offset.setX(0); offset.setY(20); this->update();}void Widget::OnLiftClicked(){ action=Widget::Move; offset.setX(-20); offset.setY(0); this->update();}void Widget::OnRightClicked(){ action=Widget::Move; offset.setX(20) ; offset.setY(0) ; this->update();}

 

转载地址:http://ibalo.baihongyu.com/

你可能感兴趣的文章
2011年9月最新整理的10个有趣的jQuery插件集合
查看>>
Python的日志配置和处理
查看>>
小程序设置全屏显示
查看>>
c++ bind的简单使用 实例
查看>>
(翻译)Angular 1.3中的验证器管道
查看>>
Web网站的性能测试工具
查看>>
【linux+C】通过几个实例温习指针
查看>>
I.MX6 Manufacturing Tool V2 (MFGTool2) Emmc mksdcard.sh hacking
查看>>
异步复位同步释放
查看>>
HDU 1241 Oil Deposits
查看>>
spring事务配置
查看>>
EALayout 实践
查看>>
Software development --daily scrum team
查看>>
B1036. 跟奥巴马一起编程(15)
查看>>
软件项目后期收官时的一些问题和想法
查看>>
机器学习:线性回归
查看>>
PHP连接PostgreSQL连接问题
查看>>
WebService案例入门(基础篇)
查看>>
回档|NOIP2012 同余方程
查看>>
久违的博客园
查看>>