Qt 图片查看器 支持鼠标缩放大小 拖动位置等_qt6 显示图片 缩放 移动-程序员宅基地

技术标签: QT学习  

由于工作需要需要编写一个图片查看器,需要支持鼠标滚动缩放大小,鼠标移动图片位置等,由于无法上传gif,截取的gif示例图暂时不上传了,讲一下大概思路

1 鼠标点击移动图片

    通过重写鼠标点击事件获取到点位,在鼠标移动事件中进行move操作,在paintEvent中指定绘制起始点即可, 与QDialog 移动操作一样,代码如下

//mousePressEvent

void PicShowDlg::mousePressEvent(QMouseEvent *event)
{
  
	QDialog::mousePressEvent(event);
	if (this->rect().contains(event->pos()))
	{
  
		QPoint p(m_pix.rect().x(),m_pix.rect().y());
		QSize size =  m_pix.size();
		m_dPixTempPos = event->globalPos() - m_dPixPos;
	}
}

//鼠标移动事件

void PicShowDlg::mouseMoveEvent(QMouseEvent *event)
{
  
	QDialog::mouseMoveEvent(event);
	if (this->rect().contains(event->pos()))
	{
  
		m_dPixPos = event->globalPos() - m_dPixTempPos;
	}
}

2 放大缩小图片

  通过重写滚轮事件,通过滚动设置比例系数,在paintEvent中重新计算缩放后的图片大小

//鼠标滚轮事件

void PicShowDlg::wheelEvent(QWheelEvent *event)
{
  
    if (event->delta() > 0)
	{
  
		m_rate -= 0.1;
		if (m_rate < 0.018)
			m_rate = 0.01;
	}
	else if (event->delta() < 0 )
	{
  
		m_rate += 0.1;
		if (m_rate >4.5)
		{
  
			m_rate = 5;
		}
	}
	update();
	return QDialog::wheelEvent(event);
}
// paintEvent 事件重新
void PicShowDlg::paintEvent(QPaintEvent *event)
{
  
	QDialog::paintEvent(event);
	QPainter p(this);
	int nH = m_pix.height()*m_rate;
	int nW = m_pix.width()*m_rate;
	QPixmap newPix = m_pix.scaled(nW,nH,Qt::KeepAspectRatio,Qt::SmoothTransformation);
	p.drawPixmap(QRect(m_dPixPos.rx()-(nW - m_pix.width())/2,m_dPixPos.ry()-(nH - m_pix.height())/2, newPix.width(),newPix.height()), newPix);
	update();
}

 

 

picShowDlg类完整代码

.h文件

 

#pragma once
 
#include <QDialog>
#include <QPixmap>
#include <QPoint>
#include "ui_PicShowDlg.h"
class PicShowDlg:public QDialog
{
  
public:
	explicit PicShowDlg(QWidget *parent = nullptr);
	~PicShowDlg();
	void SetPix(const QPixmap& pix );
	void SetPix(const QString &strFile);
 
protected:
	virtual void paintEvent(QPaintEvent *event) override;
	virtual void mousePressEvent(QMouseEvent *event) override;
	virtual void mouseMoveEvent(QMouseEvent *event) override;
	virtual void wheelEvent(QWheelEvent *event) override;
	virtual void resizeEvent(QResizeEvent *event) override;
private:
	Ui::PicShowDlg *ui;
	QPixmap m_pix;
	//QRect m_paintRect;
	QPoint m_dPixTempPos;
	QPoint m_dPixPos;
	double m_rate;
};
.cpp文件
#include <QPainter>
#include <QMouseEvent>
#include <QDesktopWidget>
#include "PicShowDlg.h"
 
PicShowDlg::PicShowDlg(QWidget *parent)
	:QDialog(parent)
	,ui(nullptr)
	, m_rate(1)
{
  
	ui = new Ui::PicShowDlg;
	ui->setupUi(this);
	this->setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint);
	this->setModal(false);
	this->show();
}
 
PicShowDlg::~PicShowDlg()
{
  
    if(ui != nullptr)
    {
  
        delete ui;
        ui = nullptr;
    }
}
 
void PicShowDlg::SetPix(const QPixmap& pix)
{
  
	m_pix = pix;
	this->resize(m_pix.size());
}
 
void PicShowDlg::SetPix(const QString &strFile)
{
  
	m_pix.load(strFile);
	this->setWindowTitle(strFile);
	if (m_pix.height() > QApplication::desktop()->height() -300)
	{
  
		this->resize(m_pix.size() + QSize(300,0));
	}
	else if(m_pix.width() > QApplication::desktop()->width() - 400)
	{
  
		this->resize(m_pix.size() + QSize(0, 200));
	}
	else
	{
  
		this->resize(m_pix.size() + QSize(300, 200));
	}
}
 
void PicShowDlg::paintEvent(QPaintEvent *event)
{
  
	QDialog::paintEvent(event);
	QPainter p(this);
	int nH = m_pix.height()*m_rate;
	int nW = m_pix.width()*m_rate;
	QPixmap newPix = m_pix.scaled(nW,nH,Qt::KeepAspectRatio,Qt::SmoothTransformation);
	p.drawPixmap(QRect(m_dPixPos.rx()-(nW - m_pix.width())/2,m_dPixPos.ry()-(nH - m_pix.height())/2, newPix.width(),newPix.height()), newPix);
	update();
}
 
void PicShowDlg::mousePressEvent(QMouseEvent *event)
{
  
	QDialog::mousePressEvent(event);
	if (this->rect().contains(event->pos()))
	{
  
		QPoint p(m_pix.rect().x(),m_pix.rect().y());
		QSize size =  m_pix.size();
		m_dPixTempPos = event->globalPos() - m_dPixPos;
	}
}
 
void PicShowDlg::mouseMoveEvent(QMouseEvent *event)
{
  
	QDialog::mouseMoveEvent(event);
	if (this->rect().contains(event->pos()))
	{
  
		m_dPixPos = event->globalPos() - m_dPixTempPos;
	}
}
 
void PicShowDlg::wheelEvent(QWheelEvent *event)
{
  
    if (event->delta() > 0)
	{
  
		m_rate -= 0.1;
		if (m_rate < 0.018)
			m_rate = 0.01;
	}
	else if (event->delta() < 0 )
	{
  
		m_rate += 0.1;
		if (m_rate >4.5)
		{
  
			m_rate = 5;
		}
	}
	update();
	return QDialog::wheelEvent(event);
}
 
void PicShowDlg::resizeEvent(QResizeEvent *event)
{
  
	this->move((QApplication::desktop()->width() - event->size().width())/2,(QApplication::desktop()->height() - event->size().height())/2);
	m_dPixPos = QPoint((event->size().width() - m_pix.width())/2,(event->size().height() - m_pix.height())/2);
	update();
}
工程代码链接 

https://download.csdn.net/download/i7891090/11975504

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/i7891090/article/details/103055899

智能推荐

习题 5-4 反片语(Ananagrams)UVa 156_输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本-程序员宅基地

文章浏览阅读385次。题目大意:输入一些单词,找出满足如下规则的单词:该单词不能通过字母重排,得到输入文本中的另外一个单词。判断时候字母不区分大小写,但是输出时候应该保留输入时候的大小写,并且按照字典序进行排序(大写字母排在小写字母前面)。实现1:(用数组模拟)#include#include#include#include#include #define maxn 1000using name_输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本

linux系统python截图不显示中文_LINUX系统python通过matplotlib绘图中文字体乱码-程序员宅基地

文章浏览阅读152次。LINUX系统python通过matplotlib绘图中文字体乱码,解决服务器里面没有字体的问题:查看环境input: 终端cat /etc/redhat-releaseoutput:CentOS Linux release 7.4.1708 (Core)服务器里面的字体路径,后续会更改该文件内容中的参数配置:input: pythonimport matplotlibmatplotlib.mat..._linux python 中文不显示

H3C交换机收集诊断信息的方法_华三交换机诊断日志怎么收集-程序员宅基地

文章浏览阅读1.5k次。(2)如选择N,会将诊断信息全部打印输出到屏幕中,建议开启终端软件的打印会话功能,记录会话功能,等待信息输出完全后,再关闭记录会话功能,输出的诊断信息都将记录在之前保存的文件中。示例:将诊断信息通过TFTP方式传给IP地址为192.168.1.100的PC上(PC上需要开启TFTP server,)(1)此时如果选择Y,则诊断信息会以文件的形式保存在设备的存储介质上,需要通过FTP或者TFTP方式下载到本地PC上。_华三交换机诊断日志怎么收集

基于Python的Climate Indices库计算SPEI(标准化降水蒸散发指数)01—Climate Indices库的下载和安装_climate-indices包-程序员宅基地

文章浏览阅读4.6k次,点赞4次,收藏45次。SPEI, Python, Climate_Indices库下载安装_climate-indices包

d3.js 旋转图形_《几何画板》画阴影图形-程序员宅基地

文章浏览阅读318次。《几何画板》画阴影图形 《几何画板》功能强大,但究其作图本质,其原理不过是提供了尺规作图的工具,当然其它的浮点运算的强大的功能另说,那个与尺规作图无关.精确的作图一是为了美观,比如电子文档或试卷的建立,二是有些平几性质的探究,本文只说一下阴影部分如何建立.比如下面的图形题:是个小奥题,虽然没有文字说明,想必大家也知道就是求其阴影部分的面积,但在电子文档中如何绘出这个图形呢?下面在《几何画板》中给出..._几何画板旋转区域阴影

Foxmail 邮件内链接无法打开问题_foxmail点击链接地址打不开-程序员宅基地

文章浏览阅读5.5k次。这两天新装了系统,然后Foxmail邮箱的邮件链接就打不开了。以前很方便就直接自动跳转到谷歌游览器上。在网上扒了半天也没解决,发现很多人都在问,今天突然折腾出来了。是我们把电脑设置里的默认游览器改了但是第三方管家里边 的默认游览器还没有改。第一种:把电脑默认游览器改为IE 游览器,就可以直接跳转到IE游览器了。但是我想大家都不愿意。第二种就是去管家(我的是腾讯电脑管家)里把默认游览器改..._foxmail点击链接地址打不开

随便推点

PID温度控制-程序员宅基地

文章浏览阅读4.3k次,点赞20次,收藏74次。PID( 位置式)温度控制_pid温度控制

Linux内核堆栈实现分析 save_stack_trace_save_stack_trace_tsk-程序员宅基地

文章浏览阅读8.3k次。1 内核线程Linux 内核为每个线程分配THREAD_SIZE(16k)的栈空间, 在每个堆栈的顶部放着struct thread_info 结构体,用来保存线程相关信息.其中有几个重要变量:Preempt_count :此变量分为四部分 0-7bit :当前进程是否能抢占的标志8-15bit:softirq 使能标志16-23bit :hardirq 使能标志..._save_stack_trace_tsk

深入MyBatis源码,理解Java设计模式之适配器模式-程序员宅基地

文章浏览阅读215次。2019独角兽企业重金招聘Python工程师标准>>> ..._mybatis源码中运用到的适配器模式

终止端口进程命令_停止端口进程命令-程序员宅基地

文章浏览阅读590次。【代码】终止端口进程命令。_停止端口进程命令

51单片机c语言俩个按键启停,51单片机跑步机启停速度控制模块仿真+源程序+电路原理图...-程序员宅基地

文章浏览阅读1.8k次。#include unsigned char code SEGtable[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //字符编码sbit SEKey =P1 ^ 0; //启动、暂停和停止按键sbit INCKey = P1 ^ 4; //速度增加键sbit DE..._顺启逆停c语言程序图

关于tomcat成功启动但访问不了欢迎界面的问题_tomcat部署成功以后服务起来了,访问不到-程序员宅基地

文章浏览阅读4.6w次,点赞16次,收藏59次。eclipse中安装tomcat的时候出现了问题。JDK已经按照网上的说法配好了,然后tomcat也成功启动。点击tomcat安装目录bin下的startup.bat后并没有出现闪退的现象。可是我在地址栏输入http://localhost:8080/却出现404错误。确认了端口号并没有被占用。百度网上一大堆也没啥用。后来发现有个帖子说是因为Root文件夹里没有index.html和index.j..._tomcat部署成功以后服务起来了,访问不到