详见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):
src_dir = QFileDialog.getExistingDirectory(self, "选择源文件夹")
if src_dir:
self.src_edit.setText(src_dir)
def select_dst_dir(self):
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(使用前将#替换为@)