This commit is contained in:
wangjialiang
2025-11-12 17:09:36 +08:00
commit 2f4a23d0ee
7 changed files with 216 additions and 0 deletions

5
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,5 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/

10
.idea/clean_unpaired_files.iml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.11 (clean_unpaired_files)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.11 (clean_unpaired_files)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (clean_unpaired_files)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/clean_unpaired_files.iml" filepath="$PROJECT_DIR$/.idea/clean_unpaired_files.iml" />
</modules>
</component>
</project>

133
gui.py Normal file
View File

@@ -0,0 +1,133 @@
import os
import shutil
from PyQt6.QtWidgets import (
QApplication, QWidget, QLabel, QLineEdit, QPushButton, QTextEdit,
QFileDialog, QVBoxLayout, QHBoxLayout, QMessageBox
)
from PyQt6.QtCore import Qt
import sys
class FileMoverGUI(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("配对文件移动工具")
self.setGeometry(200, 200, 600, 400)
# --- 控件初始化 ---
self.folder_label = QLabel("原始文件夹:")
self.folder_input = QLineEdit()
self.folder_btn = QPushButton("浏览")
self.dest1_label = QLabel("目标文件夹1 (.tiff):")
self.dest1_input = QLineEdit()
self.dest1_btn = QPushButton("浏览")
self.dest2_label = QLabel("目标文件夹2 (.xml):")
self.dest2_input = QLineEdit()
self.dest2_btn = QPushButton("浏览")
self.ext1_label = QLabel("扩展名1:")
self.ext1_input = QLineEdit(".tiff")
self.ext2_label = QLabel("扩展名2:")
self.ext2_input = QLineEdit(".xml")
self.run_btn = QPushButton("执行移动")
self.log_box = QTextEdit()
self.log_box.setReadOnly(True)
# --- 布局 ---
layout = QVBoxLayout()
def hline(label, edit, btn):
box = QHBoxLayout()
box.addWidget(label)
box.addWidget(edit)
box.addWidget(btn)
return box
layout.addLayout(hline(self.folder_label, self.folder_input, self.folder_btn))
layout.addLayout(hline(self.dest1_label, self.dest1_input, self.dest1_btn))
layout.addLayout(hline(self.dest2_label, self.dest2_input, self.dest2_btn))
ext_box = QHBoxLayout()
ext_box.addWidget(self.ext1_label)
ext_box.addWidget(self.ext1_input)
ext_box.addWidget(self.ext2_label)
ext_box.addWidget(self.ext2_input)
layout.addLayout(ext_box)
layout.addWidget(self.run_btn)
layout.addWidget(QLabel("日志输出:"))
layout.addWidget(self.log_box)
self.setLayout(layout)
# --- 信号连接 ---
self.folder_btn.clicked.connect(lambda: self.select_folder(self.folder_input))
self.dest1_btn.clicked.connect(lambda: self.select_folder(self.dest1_input))
self.dest2_btn.clicked.connect(lambda: self.select_folder(self.dest2_input))
self.run_btn.clicked.connect(self.run_script)
# 文件夹选择
def select_folder(self, target_input):
folder = QFileDialog.getExistingDirectory(self, "选择文件夹")
if folder:
target_input.setText(folder)
# 输出日志到窗口
def log(self, text):
self.log_box.append(text)
self.log_box.verticalScrollBar().setValue(self.log_box.verticalScrollBar().maximum())
QApplication.processEvents()
# 主逻辑(原 split_and_move_paired 函数的 GUI 版本)
def run_script(self):
folder = self.folder_input.text().strip()
dest1 = self.dest1_input.text().strip()
dest2 = self.dest2_input.text().strip()
ext1 = self.ext1_input.text().strip()
ext2 = self.ext2_input.text().strip()
if not all([folder, dest1, dest2, ext1, ext2]):
QMessageBox.warning(self, "输入错误", "请填写所有路径和扩展名。")
return
if not os.path.isdir(folder):
QMessageBox.critical(self, "错误", "原始文件夹无效。")
return
os.makedirs(dest1, exist_ok=True)
os.makedirs(dest2, exist_ok=True)
files_ext1 = {os.path.splitext(f)[0] for f in os.listdir(folder) if f.lower().endswith(ext1.lower())}
files_ext2 = {os.path.splitext(f)[0] for f in os.listdir(folder) if f.lower().endswith(ext2.lower())}
paired_files = files_ext1 & files_ext2
moved_count = 0
self.log_box.clear()
self.log("开始移动配对文件...\n")
for name in paired_files:
src1 = os.path.join(folder, name + ext1)
src2 = os.path.join(folder, name + ext2)
dst1 = os.path.join(dest1, name + ext1)
dst2 = os.path.join(dest2, name + ext2)
try:
shutil.move(src1, dst1)
shutil.move(src2, dst2)
moved_count += 1
self.log(f"✅ 已移动配对: {name}{ext1}{name}{ext2}")
except Exception as e:
self.log(f"⚠️ 移动失败 {name}: {e}")
self.log(f"\n总计成功移动 {moved_count} 对文件。")
self.log("剩余未配对文件已留在原目录中。")
QMessageBox.information(self, "完成", f"成功移动 {moved_count} 对文件。")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = FileMoverGUI()
window.show()
sys.exit(app.exec())

47
main.py Normal file
View File

@@ -0,0 +1,47 @@
import os
import shutil
def split_and_move_paired(folder, ext1, ext2, dest1, dest2):
"""
只移动一比一配对的文件(如 a.tiff 与 a.xml
folder: 原始文件夹
ext1, ext2: 扩展名,例如 '.tiff', '.xml'
dest1, dest2: 对应目标文件夹
"""
os.makedirs(dest1, exist_ok=True)
os.makedirs(dest2, exist_ok=True)
# 收集文件名(不含扩展名)
files_ext1 = {os.path.splitext(f)[0] for f in os.listdir(folder) if f.lower().endswith(ext1.lower())}
files_ext2 = {os.path.splitext(f)[0] for f in os.listdir(folder) if f.lower().endswith(ext2.lower())}
# 求交集:表示两种文件都存在的名字
paired_files = files_ext1 & files_ext2
moved_count = 0
for name in paired_files:
src1 = os.path.join(folder, name + ext1)
src2 = os.path.join(folder, name + ext2)
dst1 = os.path.join(dest1, name + ext1)
dst2 = os.path.join(dest2, name + ext2)
# 移动两个文件
try:
shutil.move(src1, dst1)
shutil.move(src2, dst2)
moved_count += 1
print(f"✅ 已移动配对文件: {name}{ext1}{name}{ext2}")
except Exception as e:
print(f"⚠️ 移动失败 {name}: {e}")
print(f"\n总计成功移动 {moved_count} 对文件。")
print(f"剩余未配对文件已留在原目录中。")
if __name__ == "__main__":
folder = r"E:\Train\裁剪EM14新\Output" # 原始文件夹
ext1, ext2 = ".tiff", ".xml"
dest1 = r"E:\Train\EM14IMG" # 存放 .tiff 文件的目录
dest2 = r"E:\Train\EM14XML" # 存放 .xml 文件的目录
split_and_move_paired(folder, ext1, ext2, dest1, dest2)