当前位置: 首页 > news >正文

图片查看器:用PyQt5实现本地图片预览工具

通过python代码,基于PyQt5实现本地图片预览查看工具。

我们对窗口进行了圆角设计,图片的翻页按钮半透明处理,当鼠标移动至按钮上的动画效果,当选择某一张图片,进行左右翻页则轮播同目录所有支持的图片格式。

import sys
import os
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QLabel,QPushButton, QFileDialog, QHBoxLayout, QVBoxLayout,QMessageBox)
from PyQt5.QtGui import QPixmap, QIcon, QFont, QColor, QPainter
from PyQt5.QtCore import Qt, QSize, QPoint, QPropertyAnimation, QEasingCurveclass ImageViewer(QMainWindow):def __init__(self):super().__init__()self.current_file = Noneself.files = []self.current_index = -1self.original_pixmap = None  # 存储原始图片数据self.initUI()def initUI(self):# 窗口设置self.setWindowTitle('一个黑客创业者')self.setGeometry(100, 100, 1280, 800)self.setMinimumSize(800, 600)# 深色主题样式self.setStyleSheet("""QMainWindow {background-color: #1A1A1A;}QLabel#imageLabel {background-color: #000000;border: none;}#openButton {background-color: #4A90E2;color: white;padding: 12px 24px;border-radius: 8px;font-family: 'Segoe UI';font-size: 14px;min-width: 120px;}#openButton:hover {background-color: #357ABD;}#openButton:pressed {background-color: #2A5F8F;}#navButton {background-color: rgba(0, 0, 0, 0.5);color: rgba(255, 255, 255, 0.9);border-radius: 30px;font-size: 24px;}#navButton:hover {background-color: rgba(0, 0, 0, 0.7);}#navButton:disabled {color: rgba(255, 255, 255, 0.3);}""")# 主窗口部件central_widget = QWidget()self.setCentralWidget(central_widget)main_layout = QVBoxLayout(central_widget)main_layout.setContentsMargins(0, 0, 0, 0)main_layout.setSpacing(0)# 图片显示区域self.image_label = QLabel()self.image_label.setObjectName("imageLabel")self.image_label.setAlignment(Qt.AlignCenter)main_layout.addWidget(self.image_label)# 底部控制栏self.create_bottom_bar()# 悬浮导航按钮self.create_floating_controls()# 初始化按钮状态self.update_nav_buttons()def create_bottom_bar(self):# 底部控制栏bottom_bar = QWidget()bottom_bar.setFixedHeight(80)bottom_bar.setStyleSheet("background-color: rgba(26, 26, 26, 0.9);")layout = QHBoxLayout(bottom_bar)layout.setContentsMargins(40, 0, 40, 0)self.btn_open = QPushButton(" 打开图片", self)self.btn_open.setObjectName("openButton")self.btn_open.setIcon(QIcon.fromTheme("document-open"))self.btn_open.setIconSize(QSize(20, 20))layout.addStretch()layout.addWidget(self.btn_open)layout.addStretch()self.centralWidget().layout().addWidget(bottom_bar)# 信号连接self.btn_open.clicked.connect(self.open_image)def create_floating_controls(self):# 左侧导航按钮self.btn_prev = QPushButton("◀", self)self.btn_prev.setObjectName("navButton")self.btn_prev.setFixedSize(60, 60)# 右侧导航按钮self.btn_next = QPushButton("▶", self)self.btn_next.setObjectName("navButton")self.btn_next.setFixedSize(60, 60)# 为每个按钮创建独立的动画对象self.prev_animation = QPropertyAnimation(self.btn_prev, b"pos")self.prev_animation.setEasingCurve(QEasingCurve.OutQuad)self.next_animation = QPropertyAnimation(self.btn_next, b"pos")self.next_animation.setEasingCurve(QEasingCurve.OutQuad)# 信号连接self.btn_prev.clicked.connect(self.prev_image)self.btn_next.clicked.connect(self.next_image)def resizeEvent(self, event):# 更新按钮位置nav_y = self.height() // 2 - 30self.btn_prev.move(30, nav_y)self.btn_next.move(self.width() - 90, nav_y)# 更新图片显示(使用缓存的原始图片)self.update_pixmap()super().resizeEvent(event)def open_image(self):try:file_path, _ = QFileDialog.getOpenFileName(self, "选择图片", "","图片文件 (*.png *.jpg *.jpeg *.bmp *.gif)")if file_path:self.load_image(file_path)self.update_file_list(file_path)except Exception as e:self.show_error("打开失败", str(e))def load_image(self, file_path):try:pixmap = QPixmap(file_path)if pixmap.isNull():raise ValueError("不支持的图片格式")self.original_pixmap = pixmap  # 保存原始图片self.update_pixmap()self.current_file = file_pathexcept Exception as e:self.show_error("加载失败", str(e))self.image_label.clear()def update_pixmap(self):"""根据当前窗口尺寸更新显示图片"""if self.original_pixmap:scaled = self.original_pixmap.scaled(self.image_label.size() - QSize(2, 2),Qt.KeepAspectRatio,Qt.SmoothTransformation)self.image_label.setPixmap(scaled)def update_file_list(self, file_path):try:directory = os.path.dirname(file_path)self.files = sorted([os.path.normpath(os.path.join(directory, f))for f in os.listdir(directory)if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))])normed_file_path = os.path.normpath(file_path)if normed_file_path not in self.files:raise FileNotFoundError(f"{normed_file_path} 不在这个目录中")self.current_index = self.files.index(normed_file_path)self.update_nav_buttons()except Exception as e:self.show_error("列表更新失败", str(e))def prev_image(self):if self.current_index > 0:self.current_index -= 1self.load_image(self.files[self.current_index])self.update_nav_buttons()self.animate_nav_button(self.btn_prev)def next_image(self):if self.current_index < len(self.files) - 1:self.current_index += 1self.load_image(self.files[self.current_index])self.update_nav_buttons()self.animate_nav_button(self.btn_next)def update_nav_buttons(self):self.btn_prev.setEnabled(self.current_index > 0)self.btn_next.setEnabled(self.current_index < len(self.files) - 1)def animate_nav_button(self, button):"""改进后的按钮动画方法"""animation = self.prev_animation if button == self.btn_prev else self.next_animationoriginal_pos = button.pos()offset = QPoint(-10, 0) if button == self.btn_prev else QPoint(10, 0)animation.stop()animation.setStartValue(original_pos + offset)animation.setEndValue(original_pos)animation.setDuration(200)animation.start()def show_error(self, title, message):QMessageBox.critical(self, title,f"<span style='color:#fff;font-size:14px;'>{message}</span>",QMessageBox.Ok)if __name__ == '__main__':app = QApplication(sys.argv)# 设置全局字体font = QFont("Microsoft YaHei" if sys.platform == 'win32' else "Arial")app.setFont(font)viewer = ImageViewer()viewer.show()sys.exit(app.exec_())

相关文章:

图片查看器:用PyQt5实现本地图片预览工具

通过python代码&#xff0c;基于PyQt5实现本地图片预览查看工具。 我们对窗口进行了圆角设计&#xff0c;图片的翻页按钮半透明处理&#xff0c;当鼠标移动至按钮上的动画效果&#xff0c;当选择某一张图片&#xff0c;进行左右翻页则轮播同目录所有支持的图片格式。 import …...

Deepin通过二进制方式升级部署高版本 Docker

一、背景&#xff1a; 在Deepin系统中通过二进制方式升级部署高版本 Docker&#xff0c;下面将详细介绍二进制方式升级部署高版本 Docker 的具体步骤。 二、操作步骤 1.根据需求下载二进制文件&#xff0c;下载地址如下&#xff1a; https://mirrors.tuna.tsinghua.e…...

车架号VIN查询 API 接口用JAVA如何调用?

以下是车架号VIN查询 API 接口用JAVA如何调用的示例代码&#xff1a; package com.shuxun.data.impl.demo;import com.shuxun.common.core.util.HttpUtil; import org.apache.commons.codec.digest.DigestUtils;import java.util.HashMap; import java.util.Map;public class …...

Vulnhub 靶机 VulnOSv2 write up opendocman cms 32075 sql注入 账号密码 ssh连接 37292.c 脏牛提权

Vulnhub 靶机 VulnOSv2 write up opendocman cms 32075 sql注入 账号密码 ssh连接 37292.c 脏牛提权 一、信息收集 1、首先拿到靶场先扫一下ip arp-scan -l 3、 2、指纹扫描 nmap -sS -sV 192.168.66.178nmap -p- -sV -A 192.168.66.253 PORT STATE SERVICE VERSION 22…...

爬虫的精准识别:基于 User-Agent 的正则实现

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

Python数据分析之数据可视化

Python 数据分析重点知识点 本系列不同其他的知识点讲解&#xff0c;力求通过例子让新同学学习用法&#xff0c;帮助老同学快速回忆知识点 可视化系列&#xff1a; Python基础数据分析工具数据处理与分析数据可视化机器学习基础 四、数据可视化 图表类型与选择 根据数据特…...

【免费】2004-2020年各省货运量数据

2004-2020年各省货运量数据 1、时间&#xff1a;2004-2020年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;行政区划代码、地区、年份、货运量(万吨) 4、范围&#xff1a;31省 5、指标解释&#xff1a;货运量指在一定时期内&#xff0c;各种运输工具实际运…...

【CXX】6.6 UniquePtr<T> — std::unique_ptr<T>

std::unique_ptr 的 Rust 绑定称为 UniquePtr。有关 Rust API 的文档&#xff0c;请参见链接。 限制&#xff1a; 目前仅支持 std::unique_ptr<T, std::default_delete>。未来可能会支持自定义删除器。 UniquePtr 不支持 T 为不透明的 Rust 类型。对于在语言边界传递不…...

Java 集合框架大师课:集合框架源码解剖室(五)

&#x1f525;Java 集合框架大师课&#xff1a;集合框架源码解剖室&#xff08;五&#xff09; &#x1f4a3; 警告&#xff1a;本章包含大量 裸码级硬核分析&#xff0c;建议搭配咖啡因饮料阅读&#xff01;☕️ 第一章 ArrayList 的扩容玄学 1.1 动态扩容核心代码大卸八块 …...

llamafactory 微调教程

文章目录 llamlafactory微调deepseekr1-0.5b1.1 说明1.2 搭建环境创建GPU实例连接实例部署llama_factory创建隧道&#xff0c;配置端口转发访问llama_factory 1.3 微调大模型从huggingface上下载基座模型查看模型是否下载成功准备数据集微调评估微调效果导出合并后的模型 释放实…...

代码随想录|二叉树|04二叉树的统一迭代法

一刷我这里放了。。。 代码随想录...

【教学类-43-25】20240311 数独3宫格的所有可能(图片版 12套样式,空1格-空8格,每套510张,共6120小图)

背景需求&#xff1a; 有一位客户买3宫格所有可能&#xff08;WORD表格版&#xff09; 【教学类-43-25】20241203 数独3宫格的所有可能-使用模版替换-用时少报错少&#xff08;12套样式&#xff0c;空1格-空8格&#xff0c;每套510张&#xff0c;共6120小图&#xff09;_数独三…...

Manus AI:多语言手写识别的技术革命与未来图景

摘要&#xff1a;在全球化浪潮下&#xff0c;跨语言沟通的需求日益迫切&#xff0c;但手写文字的多样性却成为技术突破的难点。Manus AI凭借其多语言手写识别技术&#xff0c;将潦草笔迹转化为精准数字文本&#xff0c;覆盖全球超百种语言。本文从技术原理、应用场景、行业价值…...

领域驱动设计(DDD)是什么?

领域驱动设计&#xff08;DDD&#xff09;是什么&#xff1f; 在软件开发的世界里&#xff0c;我们总在寻找那把打开业务之门的钥匙。有人迷恋MVC的简洁&#xff0c;有人追逐微服务的潮流&#xff0c;而DDD&#xff08;领域驱动设计&#xff09;则像一位沉默的智者&#xff0c;…...

JavaScript 模块 vs C# 类:封装逻辑的两种哲学

引言 在现代软件开发中&#xff0c;模块化和面向对象设计是代码组织的核心课题。本文通过对比 JavaScript 模块&#xff08;ES6 Module&#xff09;与 C# 类&#xff08;Class&#xff09;的实现方式&#xff0c;探讨两种语言在封装逻辑时的不同哲学&#xff0c;并给出实际应用…...

2.2 企业级ESLint/Prettier规则定制

文章目录 1. 为什么需要企业级代码规范2. 工具选型对比3. 完整配置流程3.1 项目初始化3.2 ESLint深度配置3.3 Prettier精细配置3.4 解决规则冲突4. 高级定制方案4.1 自定义ESLint规则4.2 扩展Prettier插件5. 团队协作策略5.1 配置共享方案5.2 版本控制策略6. CI/CD集成7. 常见问…...

Linux学习(十五)(故障排除(ICMP,Ping,Traceroute,网络统计,数据包分析))

故障排除是任何 Linux 用户或管理员的基本技能。这涉及识别和解决 Linux 系统中的问题。这些问题的范围包括常见的系统错误、硬件或软件问题、网络连接问题以及系统资源的管理。Linux 中的故障排除过程通常涉及使用命令行工具、检查系统和应用程序日志文件、了解系统进程&#…...

DeepIn Wps 字体缺失问题

系统缺失字体 Symbol 、Wingdings 、Wingdings2、Wingdings3、MT—extra 字体问题 问了下DeepSeek 在应用商店安装或者在windows 里面找 装了一个GB-18030 还是不行 在windows里面复制了缺失的字体 将字体复制到DeepIn 的字体目录&#xff08;Ubuntu 应该也是这个目录&am…...

(二分 数学推导 统计公平数对的数目)leetcode 2563

数学推导&#xff1a; lower < nums[i] nums[j] < upper且0 < i < j < n 则lower-nums[j]<nums[i]<upper-nums[j] 找到这个范围的nums[i]的个数就是我们要的值 所以枚举j 在0--&#xff08;j-1&#xff09;的范围内 找到第一个大于等于lower-nums[j]…...

临界比例法PID调整-附带pidtune工具和GA算法

代码已上传&#xff1a;计算机控制系统PID参数整定法资源-CSDN文库 1背景 为了模拟PID参数整定&#xff0c;把教材上的案例进行分析。 1题目 单位闭环传递函数&#xff0c;开环传函G(s)1/((s1)(s2)), Ts0.1s, PID调整器输出后&#xff0c;接零阶保持器ZOH。 2 代码 PID含积…...

CANN/asc-devkit单核形状API文档

SetSingleShape 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言&#xff0c;原生支持C和C标准规范&#xff0c;主要由类库和语言扩展层构成&#xff0c;提供多层级API&#xff0c;满足多维场景算子开发诉求。 项目地址: https://gitcode…...

别再用filter了!MATLAB bandpass函数一键搞定信号滤波,附音乐合成与降噪实战

别再用filter了&#xff01;MATLAB bandpass函数一键搞定信号滤波&#xff0c;附音乐合成与降噪实战 信号处理工程师的日常&#xff0c;往往伴随着无数个深夜调试滤波器的痛苦回忆。从设计滤波器系数到手动补偿群延迟&#xff0c;再到反复调整截止频率&#xff0c;传统filter和…...

STM32CubeMX 实战指南:LL库外部中断配置与按键响应优化

1. STM32CubeMX与LL库外部中断入门 第一次接触STM32外部中断时&#xff0c;我被它的响应速度惊艳到了。相比轮询方式&#xff0c;中断能让CPU在按键按下瞬间立即响应&#xff0c;就像有个24小时待命的管家。STM32CubeMX这个图形化配置工具&#xff0c;把原本需要手动编写的底层…...

HC32F460移植指南:除了代码,你还需要搞定Keil、J-Flash和驱动库这三大件

HC32F460开发环境搭建实战&#xff1a;从工具链配置到驱动库迁移 第一次拿到华大HC32F460开发板时&#xff0c;我对着Keil里找不到的芯片型号和一堆陌生的驱动库文件陷入了沉思。与STM32生态相比&#xff0c;华大MCU的开发环境搭建确实存在不少"坑点"。本文将分享一套…...

3分钟掌握清华PPT模板:免费打造专业学术演示文稿的终极方案

3分钟掌握清华PPT模板&#xff1a;免费打造专业学术演示文稿的终极方案 【免费下载链接】THU-PPT-Theme 清华主题PPT模板 项目地址: https://gitcode.com/gh_mirrors/th/THU-PPT-Theme 还在为学术汇报、毕业答辩或重要演讲的PPT设计而头疼吗&#xff1f;清华大学视觉设计…...

LaTeX2Word-Equation:3秒搞定网页公式到Word的终极解决方案

LaTeX2Word-Equation&#xff1a;3秒搞定网页公式到Word的终极解决方案 【免费下载链接】LaTeX2Word-Equation Copy LaTeX Equations as Word Equations, a Chrome Extension 项目地址: https://gitcode.com/gh_mirrors/la/LaTeX2Word-Equation 还在为复制数学公式而头疼…...

面试题:模型评价指标全解析——准确率、精确率、召回率、F1、ROC、AUC、MAE、MSE、RMSE、R² 一文讲透

把“分类指标怎么看、回归指标怎么选、ROC/AUC 怎么判断模型好坏”一次讲清楚很多人在面试里被问到“模型评价指标有哪些”时&#xff0c;第一反应往往是背一串名词&#xff1a;准确率、精确率、召回率、F1、AUC、MAE、MSE、R。看似都答到了&#xff0c;实际上却很容易被继续追…...

别再手动敲命令了!用Shell的Here Document(EOF)自动化你的SFTP/MySQL登录操作

告别重复输入&#xff1a;用Here Document实现命令行自动化 每次登录SFTP服务器都要手动输入密码&#xff1f;数据库操作总得反复敲命令&#xff1f;运维工程师的日常被这些重复劳动占据了大半时间。Here Document技术正是为解放你的双手而生——这种源自Unix传统的脚本编写技巧…...

Sketch MeaXure:3步告别设计标注烦恼的TypeScript重构方案

Sketch MeaXure&#xff1a;3步告别设计标注烦恼的TypeScript重构方案 【免费下载链接】sketch-meaxure 项目地址: https://gitcode.com/gh_mirrors/sk/sketch-meaxure Sketch MeaXure是一款基于TypeScript重构的Sketch设计标注插件&#xff0c;专为解决UI设计师与开发…...

避震不是“越硬越好”:拆解阻尼、弹簧与预载的黄金三角法则

在改装领域&#xff0c;“避震越硬操控越好”几乎成了一条默认的“铁律”。不少玩家升级绞牙避震后&#xff0c;第一反应就是将阻尼旋钮拧至紧&#xff0c;以“颠”为荣&#xff0c;仿佛不如此便无法体现硬核姿态。但Cornerspeed必须指出一个被长期忽视的工程事实&#xff1a;刚…...