commit b4b1560a5499c9eacec6182500be57fb0db966fc Author: tianzhendong <1203886034@qq.com> Date: Sun Jun 19 12:11:08 2022 +0800 20220619 v1.0.0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c96e9d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,84 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe +build*/ +build-* +build-*/ +build* +!.vscode +debug/ +debug +release/ +release +cmake-build*/ +.idea/ + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b07c934 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,67 @@ +cmake_minimum_required(VERSION 3.22) +project(FileRename) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.14.2/5.14.2/mingw73_64") + +aux_source_directory(${PROJECT_SOURCE_DIR} DIR_MAIN_SRCS) +aux_source_directory(${PROJECT_SOURCE_DIR}/resources DIR_RESOURCES_SRCS) +aux_source_directory(${PROJECT_SOURCE_DIR}/src DIR_SRC_SRCS) + +find_package(Qt5 COMPONENTS + Core + Gui + Widgets + REQUIRED) + +include_directories(resources + src) + +IF (CMAKE_BUILD_TYPE STREQUAL Debug) + add_executable(${PROJECT_NAME} + resources/app_win32.rc + ${DIR_MAIN_SRCS} ${DIR_RESOURCES_SRCS} ${DIR_SRC_SRCS}) +else(CMAKE_BUILD_TYPE STREQUAL Release) + add_executable(${PROJECT_NAME} + WIN32 resources/app_win32.rc + ${DIR_MAIN_SRCS} ${DIR_RESOURCES_SRCS} ${DIR_SRC_SRCS}) +ENDIF() + +target_link_libraries(${PROJECT_NAME} + Qt5::Core + Qt5::Gui + Qt5::Widgets + ) + +if (WIN32) + set(DEBUG_SUFFIX) + if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug") + set(DEBUG_SUFFIX "d") + endif () + set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}") + if (NOT EXISTS "${QT_INSTALL_PATH}/bin") + set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..") + if (NOT EXISTS "${QT_INSTALL_PATH}/bin") + set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..") + endif () + endif () + if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll") + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + "$/plugins/platforms/") + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll" + "$/plugins/platforms/") + endif () + foreach (QT_LIB Core Gui Widgets) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "${QT_INSTALL_PATH}/bin/Qt5${QT_LIB}${DEBUG_SUFFIX}.dll" + "$") + endforeach (QT_LIB) +endif () diff --git a/README.md b/README.md new file mode 100644 index 0000000..82b743f --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# 文件重命名工具 +![](./assets/img.png) +## 环境 +- Clion 2022.1.2 +- qt 5.14.2 + +## 功能 +- 单个文件重命名 +- 文件夹多个文件重命名 + +## 模式 +### 替换模式 +> 将文件名中的旧字符串替换为新字符串 + +旧字符串为空时,将文件名设置为新字符串 + +新字符串不能存在为:/\<>?*| + +新字符串不能为空 + +### 时间戳模式 + +> 将文件名中的UTC时间戳替换为北京时间:年月日时分秒 + +旧文件名用“-”连接,为:前段名-UTC时间戳.后缀 格式 + +程序会将UTC时间戳替换为北京时间年月日时分秒格式 + +新名:前段名-北京时间.后缀 + +## 重复文件处理 +当前文件夹有重复文件时,在新名后加“-旧名”字符串 + +## 使用 +deploy目录下为生成的程序,可以直接使用 +### 替换模式 +- 输入新旧字符串,选择替换模式,点击确认 +- 选择文件或者文件夹 +![](./assets/img_2.png) + +### 时间戳模式 +- 选择时间戳模式,点击确认 +- 选择文件或者文件夹 + +![](./assets/img_1.png) + + diff --git a/assets/img.png b/assets/img.png new file mode 100644 index 0000000..6cc0f5f Binary files /dev/null and b/assets/img.png differ diff --git a/assets/img_1.png b/assets/img_1.png new file mode 100644 index 0000000..cb6345f Binary files /dev/null and b/assets/img_1.png differ diff --git a/assets/img_2.png b/assets/img_2.png new file mode 100644 index 0000000..c9c04a2 Binary files /dev/null and b/assets/img_2.png differ diff --git a/resources/close.jpeg b/resources/close.jpeg new file mode 100644 index 0000000..a8c839d Binary files /dev/null and b/resources/close.jpeg differ diff --git a/resources/favicon.ico b/resources/favicon.ico new file mode 100644 index 0000000..4f497c5 Binary files /dev/null and b/resources/favicon.ico differ diff --git a/resources/fullscreen3.jpeg b/resources/fullscreen3.jpeg new file mode 100644 index 0000000..466b711 Binary files /dev/null and b/resources/fullscreen3.jpeg differ diff --git a/resources/fullscreen4.jpeg b/resources/fullscreen4.jpeg new file mode 100644 index 0000000..401b0a8 Binary files /dev/null and b/resources/fullscreen4.jpeg differ diff --git a/resources/min.jpeg b/resources/min.jpeg new file mode 100644 index 0000000..fbd7577 Binary files /dev/null and b/resources/min.jpeg differ diff --git a/src/Rename.cpp b/src/Rename.cpp new file mode 100644 index 0000000..d185025 --- /dev/null +++ b/src/Rename.cpp @@ -0,0 +1,123 @@ +// +// Created by 12038 on 2022/6/16. +// +#include +#include "Rename.h" + +Rename::Rename(QObject *) { + +} + +Rename::~Rename() { + +} + +void Rename::renameFileSlot(const QString &filePath, const QString &strReplaced, const QString &strNew) { +// filePath.lastIndexOf('/') + renameFile(filePath, strReplaced, strNew); +} + +void Rename::renameFile(const QString &filePath, const QString &strReplaced, const QString &strNew) { + QFile file(filePath); + QFileInfo fileInfo(filePath); + qDebug()< QDateTime::currentDateTime())){ + emit newFileNameSignal(tr("时间戳有误")); + return; + }; + QString time = dateTime.toString("yyyyMMddhhmmss"); //时间戳非毫秒级 + QString time1 = dateTime.toString("yyyy-MM-dd hh:mm:ss"); + qDebug() << time1; + + newBaseName = firstName + '-' +time; + } + else if(renameMethodFlag == "替换"){ + qDebug()<<"mode"<<"替换"; + if(!baseName.contains(strReplaced)) { + emit newFileNameSignal("文件名中不存在输入的字符串"); + return; + }; + if(strNew == ""){ + emit newFileNameSignal("新替换的字符串为空"); + return; + } + if(strReplaced == "") { + newBaseName = strNew; + } + else{ + newBaseName = baseName.replace(strReplaced, strNew); + qDebug()<<"newBaseName:"<getFiles(filesDirPath); +// emit oldFileNameSignal(files); + QStringList newFiles; + for (int i = 0; i < files.count(); i++){ + QString fileName = files.at(i); + emit oldFileNameSignal(fileName); + renameFile(fileName, strReplaced, strNew); +// emit newFileNameSignal(newFile); + emit process(i + 1, files.count()); + } +} + +QStringList Rename::getFiles(const QString &filesDirPath) { + QStringList files; + QDir filesDir(filesDirPath); + QList fileInfoList = filesDir.entryInfoList(QDir::Files); + for(int i = 0; i < fileInfoList.count(); i++){ + QFileInfo fileInfo = fileInfoList.at(i); + if(fileInfo.isDir()){ +// QStringList subFiles= getFiles(fileInfo.absoluteFilePath()); +// files.append(subFiles); + continue; + } + else{ + QString fileName = fileInfo.absoluteFilePath(); + files.append(fileName); + } + } + return files; +} + +void Rename::checkBoxChangedSlot(int) { + +} + +void Rename::comboxStateChangedSlot(const QString & text) { + renameMethodFlag = text; + qDebug()<< renameMethodFlag; +} + diff --git a/src/Rename.h b/src/Rename.h new file mode 100644 index 0000000..d23f1fb --- /dev/null +++ b/src/Rename.h @@ -0,0 +1,49 @@ +// +// Created by 12038 on 2022/6/16. +// + +#ifndef DUPLICATEFILESCHECK_DUPLICATEFILES_H +#define DUPLICATEFILESCHECK_DUPLICATEFILES_H + +#include +#include +#include +#include +#include +#include + +class Rename : public QObject{ +Q_OBJECT + +public: + Rename(QObject *parent = nullptr); + ~Rename(); + +signals: + void oldFileNameSignal(const QString &); + void newFileNameSignal(const QString &); + void process(const int &, const int &); + + void singleFileSignal(const QString &); + + + +public slots: + void getFilesSlot(const QString & filesDirPath, const QString &strReplaced, const QString &strNew); + void renameFileSlot(const QString &filePath, const QString &strReplaced, const QString &strNew); + void checkBoxChangedSlot(int ); + void comboxStateChangedSlot(const QString &); + +private: + void renameFile(const QString &filePath, const QString &strReplaced, const QString &strNew); + QStringList getFiles(const QString &); + + QStringList oldList = QStringList(); + QStringList newList = QStringList(); + + QString renameMethodFlag = "替换"; + QStringList dirFiles = QStringList(); +}; + + +#endif //DUPLICATEFILESCHECK_DUPLICATEFILES_H diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..a20479a --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,10 @@ +#include +#include "widget.h" + +int main(int argc, char *argv[]) { + QApplication a(argc, argv); + qRegisterMetaType>("QHash"); + Widget w; + w.show(); + return QApplication::exec(); +} diff --git a/src/widget.cpp b/src/widget.cpp new file mode 100644 index 0000000..5670ead --- /dev/null +++ b/src/widget.cpp @@ -0,0 +1,200 @@ +// +// Created by 12038 on 2022/6/15. +// + +// You may need to build the project (run Qt uic code generator) to get "ui_Widget.h" resolved + +#include "widget.h" +#include "ui_widget.h" + +Widget::Widget(QWidget *parent) + : QWidget(parent) + , ui(new Ui::Widget) +{ + ui->setupUi(this); + //取消菜单栏 + this->setWindowFlags(Qt::FramelessWindowHint); + + //阴影边框效果 + QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(); + shadow->setBlurRadius(10); + shadow->setColor(Qt::black); + shadow->setOffset(0); + + ui->shadowWidget->setGraphicsEffect(shadow); + + //父窗口透明 + this->setAttribute(Qt::WA_TranslucentBackground); + + //最大化最小化关闭功能实现 + connect(ui->btnMax, SIGNAL(clicked()), this, SLOT(btnMaxClickedSlot())); + connect(ui->btnMin, SIGNAL(clicked()), this, SLOT(btnMinClickedSlot())); + connect(ui->btnClose, SIGNAL(clicked()), this, SLOT(btnCloseClickedSlot())); + + ui->btnMin->setStyleSheet("border-image: url(../resources/min.jpeg)"); + ui->btnMax->setStyleSheet("border-image: url(../resources/fullscreen3.jpeg)"); + ui->btnClose->setStyleSheet("border-image: url(../resources/close.jpeg)"); + + + renameFile = new Rename(); + myThread = new QThread(); + renameFile->moveToThread(myThread); + myThread->start(); + connect(renameFile, SIGNAL(destroyed(QObject *)), + myThread, SLOT(deleteLater())); + +// ui->labelTitle->setText(" 文件重命名"); + connect(ui->btnSelectFile, SIGNAL(clicked(bool)), this, SLOT(selectFileClickedSlot())); + connect(ui->btnSelectDir, SIGNAL(clicked(bool)), this, SLOT(selectDirClickedSlot())); + connect(this, SIGNAL(fileSelectedSignal(const QString &, const QString &, const QString &)), + renameFile, SLOT(renameFileSlot(const QString &, const QString &, const QString &))); + + connect(this, SIGNAL(getFilesSignal(const QString &, const QString &, const QString &)), + renameFile, SLOT(getFilesSlot(const QString &, const QString &, const QString &))); + + + connect(renameFile, SIGNAL(process(const int &, const int &)), + this, SLOT(processSlot(const int &, const int &))); + connect(renameFile, SIGNAL(oldFileNameSignal(const QString &)), + this, SLOT(oldFileNameSlot(const QString &))); + connect(renameFile, SIGNAL(newFileNameSignal(const QString &)), + this, SLOT(newFileNameSlot(const QString &))); + connect(renameFile, SIGNAL(singleFileSignal(const QString &)), + this, SLOT(newFileNameSlot(const QString &))); + + connect(ui->comboBox, SIGNAL(currentTextChanged(QString)), + renameFile, SLOT(comboxStateChangedSlot(const QString &))); + + connect(ui->btnConfirm, SIGNAL(clicked()), + this, SLOT(btnConfirmClickedSlot())); +} + +Widget::~Widget() +{ + renameFile->deleteLater(); + myThread->exit(); + myThread->wait(10 * 1000); + delete ui; +} + +void Widget::mousePressEvent(QMouseEvent *event) +{ +// QWidget::mousePressEvent(event); + QPoint mouseStartPoint = event->globalPos(); + QPoint windowLeftTopPoint = this->geometry().topLeft(); + this->mousePosInWindow = mouseStartPoint - windowLeftTopPoint; +} + +void Widget::mouseMoveEvent(QMouseEvent *event) +{ +// QWidget::mouseMoveEvent(event); + if(this->mousePosInWindow == QPoint()) return; + QPoint mousePoint = event->globalPos(); + QPoint windowLeftTopPoint = mousePoint - this->mousePosInWindow; + this->move(windowLeftTopPoint); +} + +void Widget::mouseReleaseEvent(QMouseEvent *) +{ + this->mousePosInWindow = QPoint(); +} + +void Widget::closeEvent(QCloseEvent *event) +{ + QMessageBox::StandardButton button; + button=QMessageBox::question(this,tr("退出程序"),QString(tr("确认退出程序?")),QMessageBox::Yes|QMessageBox::No); + if(button==QMessageBox::No) + { + event->ignore(); // 忽略退出信号,程序继续进行 + } + else if(button==QMessageBox::Yes) + { + event->accept(); // 接受退出信号,程序退出 + } +} + +void Widget::btnMaxClickedSlot() +{ + ui->btnMax->setStyleSheet("border-image: url(../resources/fullscreen4.jpeg)"); + if(this->isMaximized()){ + ui->layoutMain->setMargin(9); + ui->btnMax->setStyleSheet("border-image: url(../resources/fullscreen3.jpeg)"); + this->showNormal(); + } + else{ + ui->layoutMain->setMargin(0); + ui->btnMax->setStyleSheet("border-image: url(../resources/fullscreen4.jpeg)"); + this->showMaximized(); + } +} + +void Widget::btnMinClickedSlot() +{ + this->showMinimized(); +} + +void Widget::btnCloseClickedSlot() +{ + this->close(); +} + +void Widget::selectFileClickedSlot() { + if(!confirmFlag){ + QMessageBox::information(this, "提示", "请先确认配置信息:模式为"+ui->comboBox->currentText()); + return; + } + QString path = QFileDialog::getOpenFileName( + this, "选择文件", + "", + ""); + if (path == "") return; + + ui->progressBar->setValue(0); + ui->listWidget->clear(); + ui->listWidget_2->clear(); + ui->listWidget->addItem(path); + + emit fileSelectedSignal(path, ui->leMd5Show->text(), ui->lineEdit->text()); +} + +void Widget::selectDirClickedSlot() { + if(!confirmFlag){ + QMessageBox::information(this, "提示", "请先确认配置信息:模式为"+ui->comboBox->currentText()); + return; + } + QString dirPathUrl = QFileDialog::getExistingDirectory(this, "选择文件夹", ""); + ui->lineDIrShow->setText(dirPathUrl); + if (dirPathUrl == "") return; + ui->progressBar->setValue(0); + ui->listWidget->clear(); + ui->listWidget_2->clear(); +// ui->leMd5Show->clear(); + emit getFilesSignal(dirPathUrl, ui->leMd5Show->text(), ui->lineEdit->text()); +} + +void Widget::processSlot(const int &now, const int &total) { + ui->progressBar->setMaximum(total); + ui->progressBar->setValue(now); +} + +void Widget::oldFileNameSlot(const QString &oldName) { + ui->listWidget->addItem(oldName); +} + +void Widget::newFileNameSlot(const QString &newName) { + ui->listWidget_2->addItem(newName); +} + +void Widget::btnConfirmClickedSlot() { + QString s = ui->lineEdit->text(); + if(s.contains('/') || s.contains('\\') || s.contains('<') || s.contains('>') || s.contains('?') || s.contains('*') || s.contains(':') || s.contains('|') || s.contains('"')){ + QMessageBox::critical(this, "错误", "文件名中不能包含/\\|<>:?*等字符"); + return; + } + confirmFlag = true; +} + + + + + diff --git a/src/widget.h b/src/widget.h new file mode 100644 index 0000000..949a258 --- /dev/null +++ b/src/widget.h @@ -0,0 +1,68 @@ +// +// Created by 12038 on 2022/6/15. +// + +#ifndef DUPLICATEFILESCHECK_WIDGET_H +#define DUPLICATEFILESCHECK_WIDGET_H + +#include +#include +#include +#include +#include +#include "Rename.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class Widget; } +QT_END_NAMESPACE + +class Widget : public QWidget +{ +Q_OBJECT + +public: + Widget(QWidget *parent = nullptr); + ~Widget(); + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + + void closeEvent(QCloseEvent *event); + +signals: + void fileSelectedSignal(const QString &path, const QString &strReplaced, const QString &strNew); + void getFilesSignal(const QString &dirPath, const QString &strReplaced, const QString &strNew); + void comboxStateChangedSignal(const QString &); + +public slots: + void processSlot(const int &, const int &); + void oldFileNameSlot(const QString & oldName); + void newFileNameSlot(const QString & newName); + +private slots: + void btnMaxClickedSlot(); + void btnMinClickedSlot(); + void btnCloseClickedSlot(); + void selectFileClickedSlot(); + void selectDirClickedSlot(); + void btnConfirmClickedSlot(); + +private: + Ui::Widget *ui; + Rename * renameFile; + QThread *myThread; + + QPoint mousePosInWindow = QPoint(); + bool confirmFlag = false; + + +}; + + +#endif //DUPLICATEFILESCHECK_WIDGET_H diff --git a/src/widget.ui b/src/widget.ui new file mode 100644 index 0000000..37b3db9 --- /dev/null +++ b/src/widget.ui @@ -0,0 +1,538 @@ + + + Widget + + + + 0 + 0 + 800 + 600 + + + + Widget + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + #shadowWidget{ + background-color: rgb(255, 255, 255); + border-radius: 5px; + } + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 9 + + + 9 + + + + + + 0 + 0 + + + + + 微软雅黑 + 12 + + + + 文件重命名工具 + + + Qt::AlignCenter + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + 14 + 50 + false + + + + QPushButton + { + border:none; +border-image: url(../resources/min.jpeg) + } + + QPushButton:hover + { + background-color: rgb(232, 232, 232); + } + QPushButton:pressed + { + background-color: rgb(162, 162, 162); + } + + + + + + + + + + + + + + false + + + + 30 + 10 + + + + + 30 + 10 + + + + + 14 + 50 + false + + + + QPushButton + { + border:none; + } + + QPushButton:hover + { + background-color: rgb(232, 232, 232); + } + QPushButton:pressed + { + background-color: rgb(162, 162, 162); + } + + + + + + + + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + 14 + 50 + false + + + + QPushButton +{ + border:none; + border-image: url(../resources/fullscreen3.jpeg) +} +QPushButton:hover +{ + background-color: rgb(232, 232, 232); +} +QPushButton:pressed +{ + background-color: rgb(162, 162, 162); +} + + + + + + + + + + false + + + + 30 + 10 + + + + + 30 + 10 + + + + + 14 + 50 + false + + + + QPushButton + { + border:none; + } + + QPushButton:hover + { + background-color: rgb(232, 232, 232); + } + QPushButton:pressed + { + background-color: rgb(162, 162, 162); + } + + + + + + + + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + 14 + 50 + false + + + + QPushButton + { + border:none; + border-top-right-radius: 5px; +border-image: url(../resources/close.jpeg) + } + + QPushButton:hover + { + background-color: rgb(253, 0, 0); + } + QPushButton:pressed + { + background-color: rgb(211, 0, 0); + } + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 10 + + + + + + 10 + + + + Qt::LeftToRight + + + 配置 + + + Qt::AlignCenter + + + + + + + 12 + + + + false + + + false + + + + 替换 + + + + + 时间戳 + + + + + + + + + 12 + + + + + + + + + 12 + + + + + + + + + + + + 12 + + + + + + + + + 12 + + + + + + + + + + + + 12 + + + + QPushButton:hover +{ + background-color: #00aaff; +} +QPushButton:pressed +{ + background-color: rgb(0, 124, 186); + +} + + + 确认 + + + + + + + + + + + 10 + + + + 重命名 + + + Qt::AlignCenter + + + + + + + + + 12 + + + + QPushButton:hover +{ + background-color: #00aaff; +} +QPushButton:pressed +{ + background-color: rgb(0, 124, 186); + +} + + + 选择文件 + + + + + + + + 12 + + + + QPushButton:hover +{ + background-color: #00aaff; +} +QPushButton:pressed +{ + background-color: rgb(0, 124, 186); + +} + + + 选择目录 + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + +