用pyqt5写一个同步文件夹内容的小工具

2023-05-16

详见https://github.com/distiny-cool/File-Synchronization
完整代码在最下面

同步文件夹内容的小工具【点这里直接下载可执行程序】

出发点

打算把电脑上的文件备份到外部磁盘上面,但是原来已经备份过了,现在又有所修改,重新复制的话实在太慢,而且有的文件内容更新过了,有冲突时不能直接跳过,所以用pyqt5写了这个小程序用于解决这个问题。

思路

代码注释详细,可以自己修改,也可以供初学者学习pyqt5参考

from PyQt5.QtWidgets import QApplication, QDialog, QLabel, QLineEdit, QPushButton, QMessageBox, QFileDialog, QTextEdit, QHBoxLayout, QVBoxLayout, QWhatsThis
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtCore import QEvent
import shutil
import os
import sys
import ctypes

class SyncFilesWindow(QDialog):
    def __init__(self):
        super().__init__()
        filename = self.resource_path(os.path.join("ico","icon.ico"))
        icon = QIcon()
        icon.addPixmap(QPixmap(filename), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")

        # 创建文本标签和文本框
        self.src_label = QLabel("源文件夹路径:", self)
        self.src_edit = QLineEdit(self)
        self.src_button = QPushButton("选择文件夹", self)
        self.dst_label = QLabel("目标文件夹路径:", self)
        self.dst_edit = QLineEdit(self)
        self.dst_button = QPushButton("选择文件夹", self)

        # 创建文本框用于显示同步的文件名称
        self.log_edit = QTextEdit(self)

        # 创建按钮
        self.sync_button = QPushButton("同步文件", self)

        # 创建水平布局,用于放置文本框和按钮
        hbox_src = QHBoxLayout()
        hbox_src.addWidget(self.src_edit)
        hbox_src.addWidget(self.src_button)
        hbox_dst = QHBoxLayout()
        hbox_dst.addWidget(self.dst_edit)
        hbox_dst.addWidget(self.dst_button)

        # 创建垂直布局
        vbox = QVBoxLayout()
        vbox.addWidget(self.src_label)
        vbox.addLayout(hbox_src)
        vbox.addWidget(self.dst_label)
        vbox.addLayout(hbox_dst)
        vbox.addWidget(self.sync_button)
        vbox.addWidget(self.log_edit)

        # 设置布局
        self.setLayout(vbox)

        # 连接按钮的点击事件和处理函数
        self.src_button.clicked.connect(self.select_src_dir)
        self.dst_button.clicked.connect(self.select_dst_dir)
        self.sync_button.clicked.connect(self.sync_files)

        # 设置窗口的属性
        self.setGeometry(300, 300, 420, 420)
        self.setWindowTitle('文件夹同步工具')

        self.infomation()

    def event(self, event):
        if event.type()==QEvent.EnterWhatsThisMode:
            QWhatsThis.leaveWhatsThisMode()
            QMessageBox.information(self, "关于", "开发:Kody Black\n"+
            "github.com/distiny-cool/File-Synchronization")
        return QDialog.event(self,event)


    def resource_path(self, relative_path):
        if getattr(sys, 'frozen', False): 
            base_path = sys._MEIPASS
        else:
            base_path = os.path.abspath(".")
        return os.path.join(base_path, relative_path)

    def select_src_dir(self):
        # 调用 QFileDialog.getExistingDirectory() 函数弹出文件夹选择对话框
        src_dir = QFileDialog.getExistingDirectory(self, "选择源文件夹")
        # 如果用户选择了文件夹,则在文本框中显示文件夹路径
        if src_dir:
            self.src_edit.setText(src_dir)

    def select_dst_dir(self):
        # 调用 QFileDialog.getExistingDirectory() 函数弹出文件夹选择对话框
        dst_dir = QFileDialog.getExistingDirectory(self, "选择目标文件夹")
        # 如果用户选择了文件夹,则在文本框中显示文件夹路径
        if dst_dir:
            self.dst_edit.setText(dst_dir)

    def infomation(self):
        self.log_edit.append('<font color="#0078d4"><b>功能介绍:</b></font>'+'<p>'+
        '本软件会把源文件夹和目标文件夹中不同的内容复制到目标文件夹里,完全相同的文件则直接跳过,以节省你的复制时间'+'<p>'+
        '<font color="#d83b01"><b>注意:</b></font><ul><li>目标文件夹不允许是源文件夹的子文件夹</li>'+
        '<li>如果有相同的文件,则在目标文件夹中会保留最近修改过的文件</li></ul>'+
        '<p style="text-align: right;"><font color="#6e9bc5">'+'<b> by:Kody </b></font></p>')

    def sync_files(self):
        # 获取文本框中的路径
        src_dir = self.src_edit.text()
        dst_dir = self.dst_edit.text()

        self.log_edit.clear()

        if not os.path.exists(src_dir):
            QMessageBox.warning(self, "错误", "源文件夹不存在!")
            return

        if not os.path.exists(dst_dir):
            QMessageBox.warning(self, "错误", "目标文件夹不存在!")
            return
        
        # 递归同步文件夹和文件
        def sync_files(src_dir, dst_dir) -> int:

            # 如果目标文件夹不存在,则创建目标文件夹
            if not os.path.exists(dst_dir):
                os.makedirs(dst_dir)
            
            # 遍历源文件夹中的文件
            for src_path in os.listdir(src_dir):
                src_path = os.path.join(src_dir, src_path)
                dst_path = os.path.join(dst_dir, src_path.split(os.sep)[-1])

                # 如果是文件夹,则递归处理
                if os.path.isdir(src_path):
                    sync_files(src_path, dst_path)
                # 如果是文件,则复制文件
                else:
                    # 如果文件已经存在,则比较时间戳
                    if os.path.exists(dst_path):
                        # 获取文件的时间戳
                        src_mtime = os.path.getmtime(src_path)
                        dst_mtime = os.path.getmtime(dst_path)

                        # 如果源文件的时间戳更新,则复制文件
                        if src_mtime > dst_mtime:
                            self.log_edit.append("正在复制文件: " + src_path)
                            shutil.copy2(src_path, dst_path)
                    else:
                        # 将文件复制到目标文件夹
                        self.log_edit.append("正在复制文件: " + src_path)
                        shutil.copy2(src_path, dst_path)
            return 1

        # 调用递归函数同步文件
        if sync_files(src_dir, dst_dir):
            QMessageBox.information(self, "提示", "文件同步成功!")
        else:
            QMessageBox.critical(self, "错误", "文件同步失败!")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = SyncFilesWindow()
    window.show()
    sys.exit(app.exec_())

⭐️欢迎star&关注

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用pyqt5写一个同步文件夹内容的小工具 的相关文章

  • 找出一个图中所有的强连通子图

    如果一个有向图中的没对顶点都可以从通过路径可达 xff0c 那么就称这个图是强连通的 一个 strongly connected component就是一个有向图中最大的强连通子图 下图中就有三个强连通子图 xff1a 应用kosaraju
  • win7启动分区不存在,使用分区工具修正

    DiskGenius 分区右键 激活当前分区
  • getElementById获取不到td标签

    一次测试中发现 然后使用getElementById获取不到此标签 xff0c 将td改成div即可 不知道是不是单独使用td标签的问题 code
  • 应用宝YSDK支付接入技术细节

    前言 应用宝是出了名的坑 xff0c 主要体现在 xff1a 文档杂乱繁多信息不全或描述模糊文档格式不规范技术支持很不及时 并且可以明显察觉到为了兼容QQ和微信 xff0c 应用宝的接入规范有诸多不合理的地方 来来回回折腾了一周 xff0c
  • 用Word2007批量设置图片位置

    转自 xff1a http www ccw com cn college htm2010 20100727 877695 shtml Word2007的 查找和替换 功能并不仅仅可以对文字进行批量的查找替换 xff0c 还有很多神奇的功能
  • java-生产者消费者问题以及解决办法

    文章目录 1 生产者消费者问题概述2 生产者消费者问题的解决办法2 1 解决思路2 2 实现方法2 3 代码实现2 3 1 wait 和nofity 方法2 3 2 await signal 方法2 3 3 BlockingQueue阻塞队
  • 【Remote Development】VSCode 基于 SSH 进行远程开发

    系统需求 我们在 VSCode 下载由微软官方推出的 Remote SSH 插件 查看一下里面的描述 xff0c 对于远程机器的要求如下 xff1a Local A supported OpenSSH compatible SSH clie
  • git idea创建新分支,获取/合并主支代码的2个方法

    其他sql格式也在更新中 xff0c 可直接查看这个系列 xff0c 要是没有你需要的格式 xff0c 可在评论或私信我 个人目录 获取主支代码的2个方法 1 xff0c 创建一个分支 xff0c 获取主支的所有代码 xff08 场景 xf
  • spring手把手超详细讲解(基本配置,基于xml)

    spring教程 1 1 容器概述1 1 1 配置元数据1 1 2 容器的实例化1 1 3 容器的使用 1 2 bean的概述1 2 1 命名bean1 2 2 实例化Bean 1 3 依赖1 3 1 依赖注入1 3 2 使用 属性1 3
  • 18.5 重载全局new、delete、定位new及重载等

    一 xff1a 重载全局operator new和operator delete操作符 span class token macro property span class token directive hash span span cl
  • java进程占用CPU过高常见的两种情况及分析定位

    java进程爆cpu的快速定位 1 背景 在程序开发的过程中 xff0c 难免遇到进程占用cpu过高 xff08 现网居多 开发环境 xff09 的情况 xff0c 现网出现这种情况就需要及时的能定位到问题 xff0c 快速解决 xff0c
  • 【Android ViewBinding】内存泄露

    场景 在MainActivity中分别加载两个Fragment处理业务 首先触发加载SecondFragment xff1a MainActivity触发 supportFragmentManager commit add R id con
  • Shell小脚本实现一键关机/重启虚拟机

    利用Shell脚本实现一键关机 重启虚拟机 xff0c 解决每次虚拟机关机或重启都需要手动一个个关机或重启的烦恼 xff01 1 脚本一 xff1a shut sh span class token comment bin bash spa
  • LAMP环境搭建

    前言 一 在虚拟机上安装Linux系统 二 安装Apache 1 下载好后 xff0c 看了看版本 xff0c 不是太老 xff0c 就没有继续安装 2 开启Apache服务 3 设置Apache开机启动服务 4 尝试一下是否启动了服务 x
  • 小程序跳坑之安卓真机不能访问服务器的问题

    因为一项目 xff0c 有几个页面都需要访问服务器 xff0c 从服务器上下载数据 xff0c 在苹果和开发者工具上都运行完美 xff0c 唯独一款安卓手机 xff0c 访问不了 xff0c 经测试 xff0c 发现是汉字编码问题 xff0
  • python Tkinter 界面button调用多进程函数,弹出多个相同界面

    这是我的界面button command的函数start simulate 这是我的多进程函数 xff1a 点击之后 xff0c 弹出多个相同界面 把调用多进程的函数在 if name 61 61 39 main 39 这里调用就不会出现多
  • python入门之if-else语句

    文章目录 一 if语句二 elif语句三 if嵌套语句四 else语句1五 else语句2六 if else语句举例1七 if else语句举例2 一 if语句 span class token keyword if span False
  • Ubuntu 16.04 远程桌面

    1 安装xrdp sudo apt get install xrdp 2 安装vnc4server 我这里是安装xrdp的时候自动安装的 我看网上很多说是需要单独安装的 3 安装xfce4 sudo apt get install xubu
  • GitLab端口冲突 解决办法

    访问gitlab xff0c 出现 xff1a 502 GitLab在使用的过程中 xff0c 会开启80端口 xff0c 如果80端口被其他的应用程序占用 xff0c 则GitLab的该项服务不能使用 xff0c 所以访问GitLab会失
  • Android开发 之 确认凭证

    确认凭证 主要目的 xff1a 设置不用验证时间 设置为30秒 xff0c 当超过30秒后则需要重新验证身份才能操作 您的应用可以根据用户在多久之前最后一次解锁设备来验证其身份 此功能让用户不必费心记忆应用特定密码 xff0c 您也无需实现

随机推荐

  • inner join、outer join、right join、left join 之间的区别

    inner join outer join right join left join 之间的区别 一 sql的left join right join inner join之间的区别 left join 左联接 返回包括左表中的所有记录和右
  • "大泥球"仍然是最常见的软件设计

    大泥球 xff0c 是指杂乱无章 错综复杂 邋遢不堪 随意拼贴的大堆代码 这些年来 xff0c 为了对付这个泥球 xff0c 我们看到了多种指导方法 xff0c 比如SOLID GRASP 和KISS xff0c 与其他诸多年代久远的 提倡
  • 3322.org带来的麻烦

    大概是3322 org被短时间攻破 xff0c 下载他的动态域名客户端的时候下到一个病毒Trojandropper js adagent gd xff0c 把江民关了 xff0c 并且再也开不开 系统还原不行 xff0c 安全模式也进不去
  • Qt学习笔记:多线程的使用

    文章目录 前言1 何时使用线程2 QThread类实现多线程2 1 多线程的实现方法2 2 线程休眠2 3 正确结束线程 3 线程同步3 1 互斥量3 2 信号量3 3 条件变量 4 线程池参考资料 前言 程序中调用耗时的操作 xff08
  • 上位机开发笔记:环形缓冲区

    文章目录 前言1 环形缓冲区工作机制1 1 实现原理1 2 区分缓冲区满或者空1 总是保持一个存储单元为空2 使用计数数据3 镜像指示位 2 Qt实现环形缓冲区2 1 QByteArray环形缓冲区2 2 QSemaphore实现环形缓冲区
  • IDEA搭建Spring框架环境

    IDEA搭建Spring框架环境 一 spring 框架概念 spring 是众多开源 java 项目中的一员 xff0c 基于分层的 javaEE 应用一站式轻量 级开源框架 xff0c 主要核心是 Ioc 控制反转 依赖注入 与 Aop
  • SQL SERVER中索引类型包括的三种类型分别是

    xfeff xfeff 唯一索引 UNIQUE 聚集索引 CLUSTERED xff09 非聚集索引 NONCLUSTERED xff09 主键与唯一索引的区别 主键是一种约束 xff0c 唯一索引是一种索引 xff0c 两者在本质上是不同
  • _Linux多线程--生产者消费者模型篇

    文章目录 1 为何要使用生产者消费者模型2 基于BlockingQueue的生产者消费者模型3 C 43 43 queue模拟阻塞队列的生产消费模型条件变量使用规范简单测试1 BlockQueue 缓存 超市 2 ConProd cc3 结
  • HTTP、TCP的关系及状态码

    一 基本概念 1 TCP连接 手机能够使用联网功能是因为手机底层实现了TCP IP协议 xff0c 可以使手机终端通过无线网络建立TCP连接 TCP协议可以对上层网络提供接口 xff0c 使上层网络数据的传输建立在 无差别 的网络之上 建立
  • x299平台装linux系统的一些天坑

    年前实验室为了配置大内存的服务器 xff0c 受限于经费 xff0c 我们只能使用比较便宜的游戏板 xff0c 选择了微星的x299平台 xff0c 买回来自带win10 xff0c 回来的第一件事就是装linux xff0c 习惯上我会装
  • android的应用包名与代码包名

    说来惭愧 xff0c 好歹还是做了android应用这么久了 xff0c 居然不知道这个事情 参考 xff1a http www xmumu com post 2013 08 05 40052300660 http blog javia o
  • [自动驾驶]Build a Traffic Sign Recognition Program

    看 准确率98 的深度学习交通标志识别是如何做到的 xff1f 这篇文章的时候 xff0c 发现了udacity的自动驾驶课程 可惜要收费 xff0c 不过课程project在github上有 xff0c 那直接做project就好了 xf
  • Spring MVC框架的高级配置

    本文将为您提供关于Spring MVC框架的配置技巧 xff0c 以帮助管理基于Spring的web应用程序的多个实例 本配置管理主题常被学术界所忽略 xff0c 但是 xff0c 这对于现实的web开发尤为重要 本主题并不直接关联任何具体
  • ffmpeg解码花屏

    问题 xff1a 解码为YUV420转为Bitmap后显示在屏幕上时 xff0c 有三分之二为花屏 xff1a 如图 xff1a 首先用h264Visa分析帧 xff1a 已经读出了sps等信息 xff0c 这些信在解码第一帧时被写入环境变
  • 使用Hexo+Github一步步搭建属于自己的博客(基础)

    前言 xff1a 电脑系统为window 10专业版 xff0c 64位 相关步骤 xff1a 1 安装Node js和配置好Node js环境 xff0c 打开cmd命令行 xff0c 成功界面如下 2 安装Git和配置好Git环境 xf
  • OpenSSL命令学习

    OpenSSL命令学习 一 基础概念 OpenSSL是一个开放源代码的软件库包 xff0c 应用程序可以使用这个包来进行安全通信 xff0c 避免窃听 xff0c 同时确认另一端连接者的身份 这个包广泛被应用在互联网的网页服务器上 下面以问
  • 论文阅读——Shadow Attacks:Hiding and Replacing Content in Signed PDFS

    论文阅读报告 Shadow Attacks xff1a Hiding and Replacing Content in Signed PDFS 阅读背景 本次阅读的论文是由Christian Mainka Vladislav Mladeno
  • SecKill——一款超级好用的抢单软件

    软件介绍 下载地址见文章末尾 Seckill是一款使用Python和pyqt编写 xff0c 利用selenium库实现的自动化抢单软件 xff0c 它界面友好 xff0c 使用方便 xff0c 可以帮助你在购物时快人一步 xff0c 及时
  • 获取PowerShell的所有历史记录

    PowerShell默认的history命令只能查看当前窗口的历史记录 xff0c 很不方便 可以使用以下方法获取PowerShell的所有历史记录 xff0c 简单记录一下 一 PSReadline 当前版本 xff08 5 1 xff0
  • 用pyqt5写一个同步文件夹内容的小工具

    详见https github com distiny cool File Synchronization 完整代码在最下面 同步文件夹内容的小工具 点这里直接下载可执行程序 出发点 打算把电脑上的文件备份到外部磁盘上面 xff0c 但是原来