通过 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 <QWidget> #include <QtGui> class Widget : public QWidget { Q_OBJECT private : 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; 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<QMouseEvent* >(event); press=true; PreDot = mouse->pos(); } else if(event->type() == QEvent::MouseButtonRelease) { if(press) press=false; } if(event->type() == QEvent::MouseMove) //移动图片 { if(press) { QMouseEvent *mouse = dynamic_cast<QMouseEvent* >(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); QPixmap pix; pix.load(":/pic/img.jpg"); 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) ; action=Widget::None; } 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); action=Widget::None; } int NowW = ratio *pixW; int NowH = ratio *pixH; if(action==Widget::Move) //移动 { int offsetx=Alloffset.x()+offset.x(); if(abs(offsetx)>=(Paint.width()/2 + NowW/2 -10)) //限制X偏移值 { if(offsetx>0) offsetx = Paint.width()/2 + NowW/2 -10; else offsetx= -Paint.width()/2 + -NowW/2 +10; } Alloffset.setX(offsetx); int offsety=Alloffset.y()+offset.y(); if(abs(offsety)>=(Paint.height()/2 + NowH/2 -10)) //限制Y偏移值 { if(offsety>0) offsety = Paint.height()/2 + NowH/2 -10; else offsety= -Paint.height()/2 + -NowH/2 +10; } Alloffset.setY(offsety); action=Widget::None; } 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; pix = pix.scaled(NowW, NowH,Qt::KeepAspectRatio); 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(); }
原文地址:https://www.cnblogs.com/lifexy/p/9057046.html
时间: 2024-10-08 21:45:50