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

PyQt学习记录03——批量设置水印

0. 目录

PyQt学习记录01——加法计算器
PyQt学习记录02——串口助手

1. 前言

本次主要是为了学习Qt中的 QFileDialog 函数,
QFileDialog.getExistingDirectory:用于选择文件夹,返回的是一个文件夹路径。
QFileDialog.getOpenFileName: 用于选择单个文件。返回的是文件的完整路径。

以及通过importlib.util实现跨文件的函数调用,即通过将定义一个对象,动态加载和调用该py文件中的函数(详见第二小节)

希望对你有所帮助。

2. Ui界面

lineEdit 用于记录文件夹路径
lineEdit_2 用于记录水印文件路径
其余元素详见第3小节的程序代码
请添加图片描述

3. 程序代码

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog
from WaterMask import Ui_MainWindow  # 导入 WaterMask 的 UI 类
from PyQt5.QtCore import QTimer
import importlib.util # 用于动态加载2.py中的函数# 动态加载 2.py
#加载一个名为 "watermark" 的模块(可自由命名),它的文件路径是 "2.py"。
spec = importlib.util.spec_from_file_location("watermark", "2.py")
#用于创建一个模块对象watermark_module。
watermark_module = importlib.util.module_from_spec(spec)
#这行代码的作用是执行 "2.py" 文件中的代码,并将模块中的函数、类等加载到 watermark_module 对象中。
spec.loader.exec_module(watermark_module)
#调用则使用watermark_module.add_watermark_to_images(folder_path, watermark_path)class WatermarkApp(QMainWindow, Ui_MainWindow):def __init__(self):super().__init__()self.setupUi(self)  # 设置 UI 界面# 绑定按钮点击事件self.pushButton.clicked.connect(self.select_folder) # 打开文件夹路径self.pushButton_2.clicked.connect(self.select_watermark) # 打开水印路径self.pushButton_3.clicked.connect(self.process_files) # 开始转换按钮def select_folder(self):folder_path = QFileDialog.getExistingDirectory(self, "选择文件夹")if folder_path:self.lineEdit.setText(folder_path)def select_watermark(self):watermark_path, _ = QFileDialog.getOpenFileName(self, "选择水印图片", "", "Image Files (*.png *.jpg *.bmp *.jpeg)")if watermark_path:self.lineEdit_2.setText(watermark_path)def process_files(self):folder_path = self.lineEdit.text()watermark_path = self.lineEdit_2.text()if not folder_path or not watermark_path:print("请先选择文件夹和水印图片")return# 按钮按下后直接变为 “转换中”self.pushButton_3.setText("转换中")self.pushButton_3.setEnabled(False)# 延时500ms调用 2.py 中的 add_watermark_to_images 函数,传递回调函数来恢复按钮状态QTimer.singleShot(500, lambda: self.start_batch_processing(folder_path, watermark_path))def start_batch_processing(self, folder_path, watermark_path):# 调用 2.py 中的批量处理函数watermark_module.add_watermark_to_images(folder_path, watermark_path)# 批量处理完成后恢复按钮状态self.pushButton_3.setText("开始转换")self.pushButton_3.setEnabled(True)if __name__ == "__main__":app = QApplication(sys.argv)window = WatermarkApp()window.show()sys.exit(app.exec_())

需要注意的是,本次学习调用了2.py来处理复杂的水印添加功能,所以展现的的代码中,可以理解为只是一个连接ui界面和2.py中的批处理函数的中间件,即ui界面提供文件路径和开始命令,通过所展现代码传递给2.py。

注意以下仅展现的2.py的基础代码

from PIL import Image
import osdef add_watermark_to_images(folder_path, watermark_path):try:for filename in os.listdir(folder_path):file_path = os.path.join(folder_path, filename)if file_path.lower().endswith(('png', 'jpg', 'jpeg', 'bmp')):print(f"给 {file_path} 添加水印: {watermark_path}")except Exception as e:print(f"发生错误: {e}")

需要注意的是,这里使用的动态加载方法在使用pyinstaller打包为exe文件时会出现找不到2.py文件的问题,所以你需要将动态加载更改为传统import导入,同时将2.py更改为two.py

import two'''
import importlib.util # 用于动态加载2.py中的函数
# 动态加载 two.py
#加载一个名为 "watermark" 的模块(可自由命名),它的文件路径是 "two.py"。
spec = importlib.util.spec_from_file_location("watermark", "two.py")
#用于创建一个模块对象watermark_module。
watermark_module = importlib.util.module_from_spec(spec)
#这行代码的作用是执行 "two.py" 文件中的代码,并将模块中的函数、类等加载到 watermark_module 对象中。
spec.loader.exec_module(watermark_module)
#调用则使用watermark_module.add_watermark_to_images(folder_path, watermark_path)
'''
#调用则使用
two.add_watermark_to_images(folder_path, watermark_path)

4. 运行结果

点击’开始转换’后,按钮文本改变为’转换中’,同时在控制台中显示进度,转换完成后按钮恢复
请添加图片描述

相关文章:

PyQt学习记录03——批量设置水印

0. 目录 PyQt学习记录01——加法计算器 PyQt学习记录02——串口助手 1. 前言 本次主要是为了学习Qt中的 QFileDialog 函数, QFileDialog.getExistingDirectory:用于选择文件夹,返回的是一个文件夹路径。 QFileDialog.getOpenFileName&…...

vivo手机和Windows电脑连接同一个WiFi即可投屏!

虽然现在很多人喜欢刷手机,但是对于长时间需要使用手机办公的人来说,手机屏幕还是太小了,当人一天二十四小时中要花费近十个小时摆弄手机,就会渴望手机屏幕能够大一点,至少看的时候,眼睛舒服一点。 因为嫌弃…...

芯盾时代数据安全产品体系,筑牢数据安全防线

芯盾时代数据安全治理(DSG)框架,以国家法律法规、行业监管标准、行业最佳实践为依据,从数据安全战略出发,以数据分类分级为支撑,构数据安全管理体系、数据安全技术体系、数据安全运营体系与数据安全监督评价…...

异位妊娠唯一相关的是年龄(U型曲线)

异位妊娠唯一相关的是年龄(U型曲线) 简介 异位妊娠,俗称宫外孕,是指受精卵在子宫体腔以外着床发育的异常妊娠过程 。正常情况下,受精卵会在子宫内着床并发育成胎儿,但在异位妊娠中,受精卵却在…...

CTF-WEB: 利用Web消息造成DOM XSS

如果索引中有类似如下代码 <!-- Ads to be inserted here --> <div idads> </div> <script>window.addEventListener(message, function(e) {document.getElementById(ads).innerHTML e.data;}); </script>这行代码的作用是将接收到的消息内容…...

【通俗易懂说模型】一篇弄懂几个经典CNN图像模型(AlexNet、VGGNet、ResNet)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;深度学习_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. …...

Unity世界坐标转成UI坐标

Unity世界坐标转成UI坐标 介绍转换代码合并方法总结 介绍 在Unity中官方提供了很多坐标转换的API&#xff0c;但是还没有一个API是将世界坐标系转换成UI的坐标系&#xff0c;世界坐标系在屏幕中的位置是不固定的所以有时候需要转换成UI坐标系**&#xff08;注意这里不是转换成…...

自制游戏——斗罗大陆

很简陋&#xff0c;没有图&#xff0c;请见谅 // mine[0] 级数 // mine[1] 战力 //mine[2] 1 白虎 //mine[2] 2 昊天锤 //mine[2] 3 蓝银草 #include <bits/stdc.h> using namespace std; int mine[100],live3, dou 1, luo 1, da 1, bag[1000], huan 0, lia…...

MindStudio制作MindSpore TBE算子(四)算子测试(ST测试-Ascend910B/ModelArts)--失败尝试

上一节&#xff0c;MindStudio制作MindSpore TBE算子&#xff08;三&#xff09;算子测试&#xff08;ST测试&#xff09;&#xff0c;因此缺乏对应的硬件环境导致无法进行ST测试&#xff0c;导致难以自安&#xff0c;今天搞来Ascend910B服务器来填坑&#xff0c;看看是否是硬件…...

二、交换机的vlan子设备接入

一、交换机的vlan设置-CSDN博客 二、交换机的vlan子设备接入-CSDN博客 接上篇的文章&#xff0c;本文接入了子设备 网络结构如下&#xff1a; 用路由器A和POE交换机B代替第一篇中的笔记本电脑&#xff0c;路由器A和交换机B都关闭DHCP服务&#xff0c;并分别接入一个IPC&#…...

EFCore相关知识分享

EFCore相关知识分享 文章目录 EFCore相关知识分享前言EFCore 的优势SaveChang的作用EF Core 查询优化小技巧使用投影&#xff08;投影到所需的数据类型&#xff09;延迟加载&#xff08;Lazy Loading&#xff09;与显式加载&#xff08;Eager Loading&#xff09;使用 AsNoTrac…...

检测网络安全漏洞 工具 网络安全 漏洞扫描 实验

实验一的名称为信息收集和漏洞扫描 实验环境&#xff1a;VMware下的kali linux2021和Windows7 32&#xff0c;网络设置均为NAT&#xff0c;这样子两台机器就在一个网络下。攻击的机器为kali,被攻击的机器为Windows 7。 理论知识记录&#xff1a; 1.信息收集的步骤 2.ping命令…...

deepseek + kimi 高效生成PPT

1.在deepseek中生成ppt大纲 2.将大纲复制到kimi中生成PPT kimi&#xff1a;https://kimi.moonshot.cn/...

JavaWeb学习-Mybatis(增删改查)

(一)Mybatis入门程序 1.创建springboot工程,并导入 mybatis的起步依赖、mysql的驱动包。(项目工程创建完成后,自动在pom.xml文件中,导入Mybatis依赖和MySQL驱动依赖) <dependencies> <!-- mybatis起步依赖 --> <dependency> …...

软考高项(二十四)法律法规和标准规范 ★重点集萃★

&#x1f451; 个人主页 &#x1f451; &#xff1a;&#x1f61c;&#x1f61c;&#x1f61c;Fish_Vast&#x1f61c;&#x1f61c;&#x1f61c; &#x1f41d; 个人格言 &#x1f41d; &#xff1a;&#x1f9d0;&#x1f9d0;&#x1f9d0;说到做到&#xff0c;言出必行&am…...

Django中select_related 的作用

Django中这句代码Dynamic.objects.select_related(song)是什么意思&#xff1f; 在 Django 中&#xff0c;这句代码&#xff1a; Dynamic.objects.select_related(song) 的作用是 在查询 Dynamic 模型的同时&#xff0c;预加载 song 关联的外键对象&#xff0c;从而减少数据…...

vscode无法ssh连接远程机器解决方案

远程服务器配置问题 原因&#xff1a;远程服务器的 SSH 服务配置可能禁止了 TCP 端口转发功能&#xff0c;或者 VS Code Server 在远程服务器上崩溃。 解决办法 检查 SSH 服务配置&#xff1a;登录到远程服务器&#xff0c;打开 /etc/ssh/sshd_config 文件&#xff0c;确保以下…...

计算机组成原理——中央处理器(九)

在每一个清晨醒来&#xff0c;你都有一个全新的机会去塑造你的世界。无论昨日经历了多少风雨&#xff0c;今天的你依旧可以启航向梦想的彼岸。生活或许会给你设置障碍&#xff0c;但请相信&#xff0c;这些都是通往成功的垫脚石。不要让短暂的困境遮蔽了你的视野&#xff0c;因…...

网页版贪吃蛇小游戏开发HTML实现附源码!

项目背景 贪吃蛇是一款经典的休闲小游戏&#xff0c;因其简单易玩的机制和丰富的变形而深受玩家喜爱。本次开发目标是实现一款网页版贪吃蛇小游戏&#xff0c;并通过前端与后端结合的方式&#xff0c;提供一个流畅的在线体验。 实现过程 游戏逻辑设计 蛇的移动&#xff1a;…...

基于java ssm springboot选课推荐交流平台系统设计和实现

基于JavaWeb开发的 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#x1f4dd; &#x1f680;&…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...

【threejs】每天一个小案例讲解:创建基本的3D场景

代码仓 GitHub - TiffanyHoo/three_practices: Learning three.js together! 可自行clone&#xff0c;无需安装依赖&#xff0c;直接liver-server运行/直接打开chapter01中的html文件 运行效果图 知识要点 核心三要素 场景&#xff08;Scene&#xff09; 使用 THREE.Scene(…...