实现原理:接收widget的事件,paintEvent重绘地图,坐标比例什么的也是根据缩放和偏移量转换计算得出…
简单粗暴,直接上代码吧!文章来源地址https://www.toymoban.com/news/detail-546432.html
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLoggingCategory>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QPixmap>
#include <QObject>
#include <QWidget>
#include <QGraphicsView>
#include <QEvent>
#include <QTouchEvent>
#include <QDebug>
#include <QMouseEvent>
#include <QPixmap>
#include <QTime>
#include <QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void setPicture(QPixmap& image);
void zoom(qreal scale);
void translate(QPointF delta);
void doubleClick();
protected:
bool event(QEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
private:
QPixmap currentImage;
int touch_status;//0 end and default,1press 2press move
qreal horizontalOffset;//水平偏移
qreal verticalOffset;//垂直偏移
qreal scaleFactor;//放大倍率
Qt::MouseButton m_translateButton; // 平移按钮
bool m_bMouseTranslate;
qreal m_zoomDelta; // 缩放的增量
QPoint m_lastMousePos; // 鼠标最后按下的位置
int pic_fix_width;//图片宽
int pic_fix_height;//图片长
QPointF current_zoom_center;
QPointF previous_touch_point0;
QPointF previous_touch_point1;
QTime touch_time;
bool touch_success;
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);
QPixmap img("/home/one/01-QtTest/TouchTest3/brightenhance.bmp");
//QPixmap img("./brightenhance.bmp");
setPicture(img);
setAttribute(Qt::WA_AcceptTouchEvents,true);
setFocusPolicy(Qt::ClickFocus);
grabGesture(Qt::PanGesture);
grabGesture(Qt::PinchGesture);
grabGesture(Qt::SwipeGesture);
current_zoom_center.setX((qreal)width()/2);
current_zoom_center.setY((qreal)height()/2);
touch_time.start();
touch_status=0;
touch_success=false;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setPicture(QPixmap &image)
{
currentImage = image;//image.convertToFormat(QImage::Format_RGB888);
pic_fix_width=currentImage.width();
pic_fix_height=currentImage.height();
scaleFactor=1;
update();
}
void MainWindow::zoom(qreal scale)
{
qreal scalecur=scaleFactor*scale;
QPointF current_center=current_zoom_center;
if(scalecur < 1)
{
scalecur = 1;
horizontalOffset=0;
verticalOffset=0;
}
else if(scalecur > 3)
{
scalecur = 3;
horizontalOffset = current_center.rx() -(current_center.rx() - horizontalOffset)*scalecur/scaleFactor;
verticalOffset = current_center.ry() -(current_center.ry() - verticalOffset)*scalecur/scaleFactor;
}
else
{
horizontalOffset = current_center.rx() -(current_center.rx() - horizontalOffset)*scalecur/scaleFactor;
verticalOffset = current_center.ry() -(current_center.ry() - verticalOffset)*scalecur/scaleFactor;
}
scaleFactor = scalecur;
update();
}
void MainWindow::translate(QPointF delta)
{
horizontalOffset +=delta.x();
verticalOffset += delta.y();
update();
}
void MainWindow::doubleClick()
{
scaleFactor = scaleFactor > 1 ? scaleFactor = 1 : scaleFactor = 3;
if(scaleFactor == 1)
{
horizontalOffset=0;
verticalOffset=0;
}
else
{
QPointF current_center=current_zoom_center;
horizontalOffset = current_center.rx() -(current_center.rx() - horizontalOffset)*scaleFactor;
verticalOffset = current_center.ry() -(current_center.ry() - verticalOffset)*scaleFactor;
}
update();
}
bool MainWindow::event(QEvent *event)
{
switch (event->type()) {
case QEvent::Wheel:
{
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
current_zoom_center.setX(wheelEvent->pos().x());
current_zoom_center.setY(wheelEvent->pos().y());
qreal currentScaleFactor = wheelEvent->delta() > 0 ? 1.1 : 0.9;
zoom(currentScaleFactor);
return true;
}
case QEvent::MouseButtonPress:
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
previous_touch_point0.setX(mouseEvent->pos().x());
previous_touch_point0.setY(mouseEvent->pos().y());
uint x = (mouseEvent->pos().x() - horizontalOffset) / scaleFactor;
uint y = (mouseEvent->pos().y() - verticalOffset) / scaleFactor;
qDebug("x = %d",x);
qDebug("y = %d",y);
return true;
}
case QEvent::MouseMove:
{
QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);
QPointF delta;
delta.setX(mouseEvent->pos().x() - previous_touch_point0.x());
delta.setY(mouseEvent->pos().y() - previous_touch_point0.y());
translate(delta);
previous_touch_point0.setX(mouseEvent->pos().x());
previous_touch_point0.setY(mouseEvent->pos().y());
return true;
}
case QEvent::MouseButtonDblClick:
{
QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);
current_zoom_center.setX(mouseEvent->pos().x());
current_zoom_center.setY(mouseEvent->pos().y());
doubleClick();
return true;
}
case QEvent::TouchBegin:
{
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
if(touchPoints.count() == 1)
{
if(touchEvent->touchPointStates() & Qt::TouchPointPressed)
{
const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.last();
previous_touch_point0.setX(touchPoint0.pos().x());
previous_touch_point0.setY(touchPoint0.pos().y());
touch_status = 1;
}
}
else if(touchPoints.count() == 2)
{
if(touchEvent->touchPointStates() & Qt::TouchPointPressed)
{
const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
const QTouchEvent::TouchPoint& touchPoint1 = touchPoints.last();
previous_touch_point0.setX(touchPoint0.pos().x());
previous_touch_point0.setY(touchPoint0.pos().y());
previous_touch_point1.setX(touchPoint1.pos().x());
previous_touch_point1.setY(touchPoint1.pos().y());
touch_status = 1;
}
}
return true;
}
case QEvent::TouchUpdate:
{
// 2.点击后的动作
qDebug() <<"TouchUpdate";
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
if (touchPoints.count() == 2)
{
if(touchEvent->touchPointStates() & Qt::TouchPointPressed)
{
touch_status=1;
const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();
previous_touch_point0.setX(touchPoint0.pos().x());
previous_touch_point0.setY(touchPoint0.pos().y());
previous_touch_point1.setX(touchPoint1.pos().x());
previous_touch_point1.setY(touchPoint1.pos().y());
// 确定两点之前的中心点的坐标,后续区域缩放的时候使用这个中心点作为 缩放定位
current_zoom_center.setX((touchPoint0.pos().rx()+touchPoint1.pos().rx())/2);
current_zoom_center.setY((touchPoint0.pos().ry()+touchPoint1.pos().ry())/2);
}
else if(touchEvent->touchPointStates() & Qt::TouchPointMoved)
{
touch_status=2;
const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();
current_zoom_center.setX((touchPoint0.pos().rx()+touchPoint1.pos().rx())/2);
current_zoom_center.setY((touchPoint0.pos().ry()+touchPoint1.pos().ry())/2);
qreal qlines = QLineF(touchPoint0.pos(), touchPoint1.pos()).length()
/ QLineF(previous_touch_point0, previous_touch_point1).length();
qreal currentScaleFactor=qlines > 1 ? 1.1 : 0.9;
zoom(currentScaleFactor);
previous_touch_point0.setX(touchPoint0.pos().x());
previous_touch_point0.setY(touchPoint0.pos().y());
previous_touch_point1.setX(touchPoint1.pos().x());
previous_touch_point1.setY(touchPoint1.pos().y());
}
else if(touchEvent->touchPointStates() & Qt::TouchPointReleased)
{
touch_status = 0;
}
}
else if (touchPoints.count() == 1)
{
if(touchEvent->touchPointStates() & Qt::TouchPointPressed)
{
const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.last();
previous_touch_point0.setX(touchPoint0.pos().x());
previous_touch_point0.setY(touchPoint0.pos().y());
touch_status=1;
}
else if(touchEvent->touchPointStates() & Qt::TouchPointMoved)
{
touch_status=2;
const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.last();
QPointF delta;
delta.setX(touchPoint0.pos().x()-previous_touch_point0.x());
delta.setY(touchPoint0.pos().y()-previous_touch_point0.y());
translate(delta);
previous_touch_point0.setX(touchPoint0.pos().x());
previous_touch_point0.setY(touchPoint0.pos().y());
}
else if(touchEvent->touchPointStates() & Qt::TouchPointReleased)
{
}
}
return true;
}
case QEvent::TouchEnd:
{
//3. 松开
qDebug() <<"TouchEnd";
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
if(touchPoints.count()==1)
{
const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
if(touch_status==1)
{
int timecount= touch_time.restart();
if(timecount<500)
{
if(!touch_success)
{
current_zoom_center.setX(touchPoint0.pos().rx());
current_zoom_center.setY(touchPoint0.pos().ry());
zoom(true);
touch_success=true;
}
}
}
}
touch_status=0;
return true;
}
default:
break;
}
return QWidget::event(event);
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPixmap image = currentImage;
if(!image.isNull())
{
image = image.scaled(this->width()*scaleFactor, this->height()*scaleFactor, Qt::KeepAspectRatio, Qt::FastTransformation);
}
const qreal iw = image.width();
const qreal ih = image.height();
if(horizontalOffset > 0)
{
horizontalOffset=0;
}
if(verticalOffset>0)
{
verticalOffset=0;
}
if(this->width()-horizontalOffset>iw)
{
horizontalOffset=this->width()-iw;
}
if(this->height()-verticalOffset>ih)
{
verticalOffset=this->height()-ih;
}
painter.drawPixmap(horizontalOffset, verticalOffset, image);
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
update();
QWidget::resizeEvent(event);
}
文章来源:https://www.toymoban.com/news/detail-546432.html
到了这里,关于Qt触摸放大、缩小、拖拽图像的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!