经常备份手机的照片到PC,如果使用Sync类同步软件备份不存在文件多次备份问题,如果只是复制文件到PC,难免有很多文件会多次备份,要整理一下也得花点时间。就想到开发一个查找重复文件的工具,定期扫描一下备份文件夹,删除重复文件。

整个工具的开发思路比较简单,遍历目录,使用SQLite数据库存储每个文件路径及MD5值, 新文件首先计算MD5值,查找数据库是否存在相同MD5值的文件,如果存在就认位是重复文件,将相关文件信息显示。如果不存在重复文件,就将文件路径信息及MD5值加入数据库。

扫描完成后,根据用户选择可以删除选中文件。

重复文件查找器(重复文件查找删除工具开发)(1)

整体界面设计如上图所示,比较简单。这个应用中有几个重点

  1. 数据库的使用
  2. 文件列表是通过QTableWidget实现的,文件路径列实现了一个自定义控件
  3. QTabelWidget中插入控件,获取控件信息的方法

针对上面几个重点直接上代码

  1. 数据库操作,此处主要是内存数据库的命名方法

#解决再次打开时提示错误 if QSqlDatabase.contains('qt_sql_default_connection'): QSqlDatabase.removeDatabase('qt_sql_default_connection') #链接数据库,并打开 self.db = QSqlDatabase.addDatabase('QSQLITE') self.db.setDatabaseName(':memory:') if not self.db.open(): QMessageBox.warning(None, "提醒", "数据打开失败,程序退出!") sys.exit(1)

数据库,查询、插入

#创建表 query = QSqlQuery() query.exec_("""CREATE TABLE fileInfo ( id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, path VARCHAR(255) NOT NULL, md5 VARCHAR(32) NOT NULL) """) #使用MD5算法查重处理 for file in self.list_all_files(self.rootdir): md5 = self.get_file_md5(file) #print("%s %s" % (file, md5)) query.exec_("SELECT id, path FROM fileInfo WHERE md5 = '%s'" % md5) if query.next(): path = query.value(1) #print(path) self.signalMsg.emit(['DUPINFO', [path, file]]) else: #不重复文件信息写入数据库 query.prepare("INSERT INTO fileInfo (path, md5) VALUES(:path, :md5)") query.bindValue(':path', file) query.bindValue(':md5', md5) query.exec_()

2.自定义了一个控件,用来显示两个重复文件的信息

#!/usr/bin/env python #-*- encoding=utf-8 -*- import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * class DupWidgets(QWidget): def __init__(self, para:list, parent=None): super(DupWidgets, self).__init__(parent) self.param = para self.setupUI() #self.show() def setupUI(self): self.file1Ckbox = QCheckBox() self.file1Ckbox.setChecked(False) self.file1Ckbox.setText('%s' % self.param[0]) self.file2Ckbox = QCheckBox() self.file2Ckbox.setChecked(True) self.file2Ckbox.setText('%s' % self.param[1]) layout = QVBoxLayout() layout.addWidget(self.file1Ckbox) layout.addWidget(self.file2Ckbox) self.setLayout(layout) def getCheckedPathInfo(self): path = [] if self.file1Ckbox.isChecked(): path.append(self.file1Ckbox.text()) if self.file2Ckbox.isChecked(): path.append(self.file2Ckbox.text()) return path

3.QTableWidget中添加控件,及控件信息获取的方法

def tableAddItem(self, infoPara:list): self.dupFilesCnt = 1 if self.dupFilesCnt > self.tableWidget.rowCount(): self.tableWidget.setRowCount(self.tableWidget.rowCount() 1) row = self.dupFilesCnt - 1 self.tableWidget.setItem(row, 0, QTableWidgetItem("%d"% self.dupFilesCnt)) item = DupWidgets(('%s' % infoPara[0], '%s' % infoPara[1])) self.tableWidget.setCellWidget(row, 1, item)

def tableGetSelectFile(self): for row in range(self.dupFilesCnt): fileList = self.tableWidget.cellWidget(row, 1).getCheckedPathInfo() yield fileList

这里获取选中文件列表的函数中,首先获取了表格中插入的自定义控件,并调用控件的成员函数返回当前选中文件路径列表。

到此为止,这个小工具主要代码如上所示,记录以备忘。

,