231 lines
9.0 KiB
Python
231 lines
9.0 KiB
Python
from PySide6.QtWidgets import (
|
||
QApplication,
|
||
QFileDialog,
|
||
QMainWindow,
|
||
QPushButton,
|
||
QVBoxLayout,
|
||
QWidget,
|
||
QListView,
|
||
QAbstractItemView,
|
||
QTreeView,
|
||
QTableView,
|
||
QLabel,
|
||
QLineEdit,
|
||
QHBoxLayout,
|
||
QMessageBox,
|
||
QProgressBar, # 导入 QProgressBar 类
|
||
)
|
||
from PySide6.QtWidgets import QHeaderView
|
||
from PySide6.QtGui import (
|
||
QStandardItemModel,
|
||
QStandardItem,
|
||
QRegularExpressionValidator,
|
||
) # 修改 QRegExpValidator 为 QRegularExpressionValidator
|
||
from PySide6.QtCore import Slot # 导入 Slot 装饰器
|
||
from PySide6.QtCore import Qt, QRegularExpression # 导入 Qt 和 QRegularExpression 类
|
||
import core
|
||
|
||
|
||
class FolderSelectorApp(QMainWindow):
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.setWindowTitle("照片整理")
|
||
self.setGeometry(100, 100, 600, 400)
|
||
|
||
# 创建按钮
|
||
# TODO: 暂时不用选择文件夹按钮
|
||
self.select_folders_button = QPushButton("选择多个文件夹", None)
|
||
self.select_folders_button.clicked.connect(self.select_folders)
|
||
|
||
self.select_files_button = QPushButton("选择多个文件", self)
|
||
self.select_files_button.clicked.connect(self.select_files)
|
||
|
||
# 整理照片按钮
|
||
self.arrage_button = QPushButton("开始整理", self)
|
||
self.arrage_button.clicked.connect(self.arrage_pic)
|
||
|
||
# 创建文件开始计数
|
||
self.start_index_label = QLabel("目录开始基数:", self)
|
||
self.start_index_text = QLineEdit(self)
|
||
self.start_index_text.setText("1")
|
||
# 添加验证器以只接受正整数,并且当数字超过2位时,第一位不能是0
|
||
regex = QRegularExpression(
|
||
r"^(?!0\d)\d+$"
|
||
) # 正则表达式确保当数字超过2位时,第一位不能是0
|
||
validator = QRegularExpressionValidator(regex, self)
|
||
self.start_index_text.setValidator(validator)
|
||
# 创建目标文件夹
|
||
self.destination_directory_label = QLabel("保存到文件夹:", self)
|
||
self.destination_directory_text = QLineEdit(self)
|
||
self.destination_directory_text.setReadOnly(True)
|
||
self.destination_directory_text.setCursorMoveStyle(Qt.VisualMoveStyle)
|
||
|
||
# 创建QTableView
|
||
self.table_view = QTableView(self)
|
||
self.model = QStandardItemModel(0, 2, self)
|
||
self.model.setHorizontalHeaderLabels(["文件夹名称", "路径"])
|
||
self.table_view.setModel(self.model)
|
||
self.table_view.horizontalHeader().setSectionResizeMode(0, QHeaderView.Fixed)
|
||
self.table_view.setColumnWidth(0, int(self.width() * 0.3))
|
||
self.table_view.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
|
||
|
||
# 创建进度条
|
||
self.progress_bar = QProgressBar(self)
|
||
self.progress_bar.setValue(0)
|
||
|
||
# 布局
|
||
# 设置计数的布局
|
||
start_index_layout = QHBoxLayout()
|
||
start_index_layout.addWidget(self.start_index_label)
|
||
start_index_layout.addWidget(self.start_index_text)
|
||
start_index_layout.addStretch(2)
|
||
# 保持到文件夹布局
|
||
destination_directory_layout = QHBoxLayout()
|
||
destination_directory_layout.addWidget(self.destination_directory_label)
|
||
destination_directory_layout.addWidget(self.destination_directory_text)
|
||
# 选择文件的布局
|
||
layout = QVBoxLayout()
|
||
# layout.addWidget(self.select_folders_button)
|
||
layout.addLayout(start_index_layout)
|
||
layout.addLayout(destination_directory_layout)
|
||
layout.addWidget(self.select_files_button)
|
||
layout.addWidget(self.arrage_button)
|
||
layout.addWidget(self.table_view)
|
||
layout.addWidget(self.progress_bar) # 添加进度条到布局
|
||
|
||
container = QWidget(self)
|
||
# container.setLayout(start_index_layout)
|
||
container.setLayout(layout)
|
||
|
||
# container.layout.addLayout(start_index_layout)
|
||
self.setCentralWidget(container)
|
||
|
||
self.worker = None # 初始化 worker 为 None
|
||
|
||
def select_folders(self):
|
||
# 打开文件夹选择对话框,允许多选
|
||
dialog = QFileDialog(self)
|
||
dialog.setWindowTitle("请选择多个文件夹")
|
||
dialog.setFileMode(QFileDialog.Directory) # 设置为目录选择模式
|
||
dialog.setOption(
|
||
QFileDialog.DontUseNativeDialog, True
|
||
) # 使用Qt对话框以支持多选
|
||
dialog.setOption(QFileDialog.ShowDirsOnly, True) # 只显示文件夹
|
||
dialog.setOption(QFileDialog.DontResolveSymlinks, True) # 不解析符号链接
|
||
|
||
# 设置列表视图和树视图为多选模式
|
||
for view in dialog.findChildren(QListView) + dialog.findChildren(QTreeView):
|
||
view.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||
# 设置样式表,使选中项的背景色为蓝色
|
||
view.setStyleSheet(
|
||
"""QAbstractItemView::item:selected {
|
||
background-color: #0078D7;
|
||
color: white;
|
||
}
|
||
QAbstractItemView::item:selected:!active {
|
||
background-color: #CCE8FF;
|
||
color: black;
|
||
}"""
|
||
)
|
||
|
||
if dialog.exec():
|
||
folder_paths = dialog.selectedFiles() # 获取选择的文件夹路径
|
||
print("选择的文件夹路径:", folder_paths)
|
||
|
||
# 清空当前模型
|
||
self.model.removeRows(0, self.model.rowCount())
|
||
|
||
# 添加新的文件夹路径到模型
|
||
for path in folder_paths:
|
||
folder_name = (
|
||
path.split("/")[-1] if "/" in path else path.split("\\")[-1]
|
||
)
|
||
name_item = QStandardItem(folder_name)
|
||
path_item = QStandardItem(path)
|
||
self.model.appendRow([name_item, path_item])
|
||
|
||
@Slot(int) # 使用 Slot 装饰器
|
||
def update_progress(self, value):
|
||
"""更新进度条的值"""
|
||
self.progress_bar.setValue(value)
|
||
|
||
def finished_notification(self):
|
||
"""显示完成通知"""
|
||
QMessageBox.information(self, "完成", "整理完成!")
|
||
|
||
def update_destination_directory(self, path):
|
||
"""更新目标文件夹路径"""
|
||
self.destination_directory_text.setText(path)
|
||
|
||
def arrage_pic(self):
|
||
# 获取table_view中第一列的数据
|
||
name_list = []
|
||
for row in range(self.model.rowCount()):
|
||
item = self.model.item(row, 1)
|
||
if item is not None:
|
||
name_list.append(item.text())
|
||
if len(name_list) == 0:
|
||
QMessageBox.warning(self, "警告", "请选择文件!")
|
||
return
|
||
|
||
# 设置进度条的最大值
|
||
self.progress_bar.setMaximum(len(name_list))
|
||
self.progress_bar.setValue(0)
|
||
|
||
# 创建 Worker 实例
|
||
self.worker = core.Worker(
|
||
name_list, start_index=int(self.start_index_text.text())
|
||
)
|
||
self.worker.progress.connect(self.update_progress) # 连接信号到槽函数
|
||
self.worker.finished.connect(self.worker.deleteLater) # 任务完成后删除 worker
|
||
self.worker.finished.connect(self.finished_notification) # 完成后提示
|
||
self.worker.destination_directory.connect(
|
||
self.update_destination_directory
|
||
) # 给出目标文件夹路径
|
||
self.worker.start() # 启动线程
|
||
|
||
def resizeEvent(self, event):
|
||
super().resizeEvent(event)
|
||
self.table_view.setColumnWidth(0, int(self.width() * 0.3))
|
||
|
||
def select_files(self):
|
||
# 打开文件选择对话框,允许多选
|
||
dialog = QFileDialog(self)
|
||
dialog.setWindowTitle("请选择多个文件")
|
||
dialog.setFileMode(QFileDialog.ExistingFiles) # 设置为文件选择模式
|
||
dialog.setNameFilter(
|
||
"JPG Files (*.jpg *.JPG)"
|
||
) # 设置文件过滤器,只允许选择jpg文件
|
||
dialog.setOption(
|
||
QFileDialog.DontUseNativeDialog, False
|
||
) # 使用Qt对话框以支持多选
|
||
|
||
# 设置列表视图和树视图为多选模式
|
||
for view in dialog.findChildren(QListView) + dialog.findChildren(QTreeView):
|
||
view.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||
# 设置样式表,使选中项的背景色为蓝色
|
||
view.setStyleSheet(
|
||
"""QAbstractItemView::item:selected {
|
||
background-color: #0078D7;
|
||
color: white;
|
||
}
|
||
QAbstractItemView::item:selected:!active {
|
||
background-color: #CCE8FF;
|
||
color: black;
|
||
}"""
|
||
)
|
||
|
||
if dialog.exec():
|
||
file_paths = dialog.selectedFiles() # 获取选择的文件路径
|
||
print("选择的文件路径:", file_paths)
|
||
|
||
# 清空当前模型
|
||
self.model.removeRows(0, self.model.rowCount())
|
||
|
||
# 添加新的文件路径到模型
|
||
for path in file_paths:
|
||
file_name = path.split("/")[-1] if "/" in path else path.split("\\")[-1]
|
||
name_item = QStandardItem(file_name)
|
||
path_item = QStandardItem(path)
|
||
self.model.appendRow([name_item, path_item])
|