Qt实现长图片的放大缩小以及动态显示

这篇文章是在这个基础上进行讨论的谈一谈分别利用opencv、Qt、matlab动态显示图片的实现

其实就是想找一种更加合适的方法进行图片的放大缩小以及动态显示。

这个是效果图

 

我把项目命名为Qtmline,因为之前做了和Qtimeline有关的东西

我们关心的是header files和source files里的文件

先说header files里的pixitem.h,放代码

 

#ifndef PIXITEM_H
#define PIXITEM_H

#include <QGraphicsItem>
#include <QPixmap>
#include <QPainter>
#include <QRectF>
#include <QMouseEvent>
#include <QPointF>
#include <QDragEnterEvent>
#include <QGraphicsSceneWheelEvent>

enum Enum_ZoomState{
    NO_STATE,
    RESET,
    ZOOM_IN,
    ZOOM_OUT
};

enum Enum_ZoomTimes{
    ZOOM_IN_TIMES = 5,
    ZOOM_OUT_TIMES = -5,
};

class PixItem : public QGraphicsItem        //继承自图元类,实现自定义的图元,,,qt预置的有直线,椭圆,文本图元,矩形图元等
{
public:
    PixItem(QPixmap *pixmap);   //构造函数初始化了变量pix
    QRectF boundingRect() const;    //实现自己的boundingRect 图元边界方法,完成以图元坐标系为基础增加两个像素点的冗余的工作
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); //重画图形函数
    void wheelEvent(QGraphicsSceneWheelEvent *event);
    void setZoomState(const int &zoomState);

    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

    int getScaleValue() const;
    void setScaleValue(const int &);

private:
    qreal m_scaleValue;   //缩放值

    QPixmap pix;    //作为图元显示的图片
    int m_zoomState;

    bool m_isMove;
    QPointF m_startPos;
};

#endif // PIXITEM_H


与之对应的pixitem.cpp代码

 

 

#include "pixitem.h"

#include <QDebug>
#include <QGraphicsSceneMouseEvent>
#include <QPointF>
#include <QGraphicsSceneDragDropEvent>
#include <QDrag>
#include <math.h>

//构造函数初始化了变量pix
PixItem::PixItem(QPixmap *pixmap)
{
    pix = *pixmap;
    setAcceptDrops(true);   //设置可拖拽
    m_scaleValue = 0;

    m_isMove = false;
}

//实现自己的图元边界函数
QRectF PixItem::boundingRect() const
{
    return QRectF(-pix.width() / 2, -pix.height() / 2,
                  pix.width(), pix.height());
}

//只需QPainter的drawPixmap()函数将图元图片绘出即可
void PixItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
                    QWidget *)
{
    painter->drawPixmap(-pix.width() / 2, -pix.height() / 2, pix);
}

//鼠标点击事件  局部缩放
void PixItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    m_startPos = event->pos();
    m_isMove = true;

    int scaleValue = m_scaleValue;
    if(m_zoomState == ZOOM_IN)       //局部放大
    {
        scaleValue++;
    }
    else if(m_zoomState == ZOOM_OUT)        //局部缩小
    {
        scaleValue--;
    }

    if (scaleValue > ZOOM_IN_TIMES || scaleValue < ZOOM_OUT_TIMES)
        return;

    if (m_scaleValue != scaleValue)
    {
        setTransformOriginPoint(event->pos().x(), event->pos().y());
    }
    m_scaleValue = scaleValue;
    qreal s;
    //实现局部缩放
    if(m_scaleValue > 0)
    {
        s = pow(1.1, m_scaleValue);        //放大 计算x的y方次 参数都是double类型
    }else
    {
        s = pow(1 / 1.1, -m_scaleValue);      //缩小
    }
    setScale(s);
}

void PixItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if(m_isMove)
    {
        QPointF point = event->pos() - m_startPos;
        moveBy(point.x(), point.y());
    }
}

void PixItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
{
    m_isMove = false;
}

//使用滚轮整体缩放
void PixItem::wheelEvent(QGraphicsSceneWheelEvent *event)
{
    setZoomState(NO_STATE);

    int scaleValue = m_scaleValue;
    if(event->delta() > 0)  //delta()为正,滚轮向上滚
    {
        scaleValue++;
    }
    else
    {
        scaleValue--;
    }

    if (scaleValue > ZOOM_IN_TIMES || scaleValue < ZOOM_OUT_TIMES)
        return;

    m_scaleValue = scaleValue;
    qreal s;
    if(m_scaleValue > 0)
    {
        s = pow(1.1, m_scaleValue);        //放大 计算x的y方次 参数都是double类型
    }
    else
    {
        s = pow(1 / 1.1, -m_scaleValue);      //缩小
    }
    setScale(s);
    setTransformOriginPoint(event->pos().x(), event->pos().y());
}

//从widget获取的缩放值,用于同步滚轮和按键
void PixItem::setScaleValue(const int &scaleValue)
{
    if (scaleValue > ZOOM_IN_TIMES || scaleValue < ZOOM_OUT_TIMES)
        return;

    m_scaleValue = scaleValue;

    qreal s;
    if(m_scaleValue > 0)
    {
        s = pow(1.1, m_scaleValue);        //放大 计算x的y方次 参数都是double类型
    }
    else
    {
        s = pow(1 / 1.1, -m_scaleValue);      //缩小
    }

    setScale(s);
}

void PixItem::setZoomState(const int &zoomState)
{
    m_zoomState = zoomState;
    if (m_zoomState == RESET)
    {
        m_scaleValue = 0;
        setScale(1);
        setTransformOriginPoint(0, 0);
    }
}

int PixItem::getScaleValue() const
{
    return m_scaleValue;
}


Qtmline.h中是这样的

 

 

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_Qtmline.h"
#include <QProgressBar>
#include <QVBoxLayout>
#include <QPushButton>
#include <QTimeLine>
#include <QGraphicsEllipseItem>
#include <QGraphicsItemAnimation>
#include <QGraphicsScene>
#include <QGraphicsView>
#include "pixitem.h"
#include <QPixmap>
#include <QLabel>
#include <QTimerEvent>


class Qtmline : public QMainWindow
{
	Q_OBJECT

public:
	Qtmline(QWidget *parent = Q_NULLPTR);
	
private slots:
    int OnBtnStart();
	int OnBtnBig();
	int OnBtnMove();
private:
	Ui::QtmlineClass ui;


	PixItem *m_pixItem;

	QGraphicsScene *m_graphicsScene;

	QGraphicsView *m_graphicsView;
	int m_timerId;
	void timerEvent(QTimerEvent * event);
	int m_flag;
};


Qtmline.cpp是这样的

 

 

#include "Qtmline.h"
#include <QMessageBox>


Qtmline::Qtmline(QWidget *parent)
	: QMainWindow(parent),m_flag(0)
{
	ui.setupUi(this);
	m_timerId = startTimer(60);
	connect(ui.BtnStart, SIGNAL(clicked()), SLOT(OnBtnStart()));
	connect(ui.BtnBig, SIGNAL(clicked()), SLOT(OnBtnBig()));
	connect(ui.BtnMove, SIGNAL(clicked()), SLOT(OnBtnMove()));
}
int Qtmline::OnBtnStart()
{

	
	QGraphicsScene *m_graphicsScene = new QGraphicsScene;
	m_graphicsScene->setSceneRect(-200, -200, 400, 400);
	QPixmap *pixmap = new  QPixmap("D:\\000.png");
	m_pixItem = new PixItem(pixmap);
	m_graphicsScene->addItem(m_pixItem);
	m_pixItem->setPos(0, 600);

	m_graphicsView = new QGraphicsView;
	m_graphicsView->setScene(m_graphicsScene);
	m_graphicsView->setMinimumSize(400, 400);
	ui.GLayout->addWidget(m_graphicsView);
	
	
	//QMessageBox::information(this, "ok", "Successful Connect");

	return 0;
}
int Qtmline::OnBtnBig()
{
	//QMessageBox::information(this, "ok", "Successful Connect");

	m_graphicsView->scale(2, 2);
	return 0;
}

int Qtmline::OnBtnMove()
{
	//QMessageBox::information(this, "ok", "Successful Connect");
	
	m_flag = 1;
	return 0;
}
void Qtmline::timerEvent(QTimerEvent * event)
{
	// 可以有多个定时器,每个的定时器有不同的处理  
	if (event->timerId() == m_timerId&&m_flag==1)
	{
		m_pixItem->moveBy(0, -50);
		update(); // 重绘  
	}
}


main.cpp是这样的

 

 

#include "Qtmline.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	
	Qtmline w;
	w.show();

	return a.exec();
}




接下来介绍Qtmline.ui文件

 

这个直接拖进来就行,我命名成了GLayout它是Grid Layout 类中的

然后是三个按钮

具体的代码仔细看就明白了,显示主要是这个

 

	QGraphicsScene *m_graphicsScene = new QGraphicsScene;
	m_graphicsScene->setSceneRect(-200, -200, 400, 400);
	QPixmap *pixmap = new  QPixmap("D:\\000.png");
	m_pixItem = new PixItem(pixmap);
	m_graphicsScene->addItem(m_pixItem);
	m_pixItem->setPos(0, 600);

	m_graphicsView = new QGraphicsView;
	m_graphicsView->setScene(m_graphicsScene);
	m_graphicsView->setMinimumSize(400, 400);
	ui.GLayout->addWidget(m_graphicsView);


移动主要是通过Qtime实现的

void Qtmline::timerEvent(QTimerEvent * event)
{
	// 可以有多个定时器,每个的定时器有不同的处理  
	if (event->timerId() == m_timerId&&m_flag==1)
	{
		m_pixItem->moveBy(0, -50);
		update(); // 重绘  
	}
}

 

 

 

放大缩小是由这个方法

 

int Qtmline::OnBtnBig()
{
	//QMessageBox::information(this, "ok", "Successful Connect");

	m_graphicsView->scale(2, 2);
	return 0;
}

上面是放大的,缩小就可以这样改

 

 

int Qtmline::OnBtnBig()
{
	//QMessageBox::information(this, "ok", "Successful Connect");

	m_graphicsView->scale(0.8, 0.8);
	return 0;
}

可以点击下面的链接下载pixitem类
pixitem类
 

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值