最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python結合PyQt5編寫一個批量目錄重命名工具并打包成EXE

 更新時間:2026年01月21日 09:06:33   作者:小莊-Python辦公  
這篇文章主要為大家詳細介紹了Python如何結合PyQt5編寫一個批量目錄重命名工具,并打包成帶圖標的 EXE,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

目錄整理是一個非常常見但又枯燥的工作:比如下載了一堆帶前綴/后綴的文件夾、備份目錄前面都想加上日期、把目錄名中的空格統(tǒng)一改成下劃線……手工一個個改,很容易改到崩潰。

這篇文章記錄我用 PyQt5 做了一個圖形界面的小工具:支持對某個目錄下所有子目錄名進行 批量重命名,并且可以:

  • 前面添加(前綴)
  • 后面添加(后綴)
  • 替換某個子串
  • 刪除某個子串
    更重要的是:這些操作可以 疊加使用,按順序從上到下執(zhí)行。

最后再用 PyInstaller 打包成帶自定義圖標的單文件 renamedir.exe,方便在任何 Windows 上直接雙擊使用。

一、功能設計:從「單操作」到「規(guī)則流水線」

一開始的需求很簡單:

選定一個目錄,然后對它下面的一級子目錄做統(tǒng)一的「前面添加 / 后面添加 / 替換 / 刪除」。

這個版本的界面大概是這樣:

  • 一個「目標目錄」選擇框
  • 一個「操作類型」下拉框(前面添加 / 后面添加 / 替換 / 刪除)
  • 兩個參數(shù)輸入框(比如「要替換」「替換為」)
  • 一個「預覽」按鈕
  • 一個下方表格,顯示「原目錄名」「新目錄名」「狀態(tài)」
  • 一個「執(zhí)行重命名」按鈕

后來實際使用中,很快發(fā)現(xiàn)一個限制:

實際需求往往不是「只做一個操作」,而是類似:

  • 先把目錄名里的 test 都刪掉
  • 再把空格替換成 _
  • 最后前面加上日期前綴,比如 2026_

如果每次只能做一個操作,就要手動來回切換參數(shù)、預覽、執(zhí)行,非常不方便。

于是把「單次操作」升級成了 可疊加的規(guī)則列表:像流水線一樣依次應用。

設計改動:

  • 之前的「操作類型 + 參數(shù)」區(qū)域變成「規(guī)則編輯器」
  • 下面新增一個「規(guī)則列表表格」
  • 支持:
    • 點擊「添加規(guī)則」把當前操作加入列表
    • 規(guī)則上移 / 下移調整順序
    • 刪除單條規(guī)則
    • 一鍵清空全部規(guī)則
  • 預覽時,會對每個目錄名按規(guī)則列表的順序依次執(zhí)行

這樣就可以放心地配置「先刪、再替換、再加前綴/后綴」等組合操作了。

二、界面布局:一個小而美的 PyQt5 窗口

整個界面由三個部分組成:

  • 頂部:目標目錄區(qū)域
  • 中間:規(guī)則配置區(qū)域
  • 底部:預覽和執(zhí)行

1. 目標目錄區(qū)域

使用 QGroupBox + QHBoxLayout

  • 標簽:路徑
  • 輸入框:self.dir_edit
  • 瀏覽按鈕:瀏覽...,通過 QFileDialog.getExistingDirectory 讓用戶選擇目錄
dir_group = QGroupBox("目標目錄")
dir_layout = QHBoxLayout()
dir_label = QLabel("路徑")
self.dir_edit = QLineEdit()
browse_btn = QPushButton("瀏覽...")
browse_btn.clicked.connect(self.browse_dir)
dir_layout.addWidget(dir_label)
dir_layout.addWidget(self.dir_edit, 1)
dir_layout.addWidget(browse_btn)
dir_group.setLayout(dir_layout)
main_layout.addWidget(dir_group)

browse_dir 很簡單,從對話框拿到目錄再寫入輸入框:

def browse_dir(self):
    directory = QFileDialog.getExistingDirectory(self, "選擇目標目錄")
    if directory:
        self.dir_edit.setText(directory)

2. 規(guī)則配置區(qū)域:編輯 + 列表

規(guī)則區(qū)域用了一個大的 QGroupBox("規(guī)則設置"),里面再嵌兩個部分:

  • 上半:規(guī)則編輯器(操作類型 + 參數(shù)1 + 參數(shù)2 + 添加規(guī)則按鈕)
  • 下半:當前規(guī)則列表(表格)+ 規(guī)則操作按鈕

規(guī)則編輯器部分:

builder_form = QFormLayout()

op_label = QLabel("操作類型")
self.op_combo = QComboBox()
self.op_combo.addItem("前面添加", "prefix")
self.op_combo.addItem("后面添加", "suffix")
self.op_combo.addItem("替換", "replace")
self.op_combo.addItem("刪除字符", "delete")

self.param1_label = QLabel("參數(shù)1")
self.param1_edit = QLineEdit()
self.param2_label = QLabel("參數(shù)2")
self.param2_edit = QLineEdit()

builder_form.addRow(op_label, self.op_combo)
builder_form.addRow(self.param1_label, self.param1_edit)
builder_form.addRow(self.param2_label, self.param2_edit)

add_row = QHBoxLayout()
add_row.addStretch()
self.add_op_btn = QPushButton("添加規(guī)則")
add_row.addWidget(self.add_op_btn)
builder_form.addRow(QLabel(""), add_row)

規(guī)則列表表格:

self.ops_table = QTableWidget()
self.ops_table.setColumnCount(4)
self.ops_table.setHorizontalHeaderLabels(["順序", "類型", "參數(shù)1", "參數(shù)2"])
self.ops_table.setAlternatingRowColors(True)
self.ops_table.setSelectionBehavior(QAbstractItemView.SelectRows)
self.ops_table.setSelectionMode(QAbstractItemView.SingleSelection)
self.ops_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.ops_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)
self.ops_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeToContents)
self.ops_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch)
self.ops_table.horizontalHeader().setSectionResizeMode(3, QHeaderView.Stretch)
self.ops_table.verticalHeader().setVisible(False)
self.ops_table.setShowGrid(False)

表格下面是幾個操作按鈕:

  • 上移
  • 下移
  • 刪除
  • 清空

3. 預覽 / 執(zhí)行區(qū)域

兩個主按鈕:

btn_layout = QHBoxLayout()
self.preview_btn = QPushButton("預覽")
self.apply_btn = QPushButton("執(zhí)行重命名")
btn_layout.addStretch()
btn_layout.addWidget(self.preview_btn)
btn_layout.addWidget(self.apply_btn)
main_layout.addLayout(btn_layout)

下方結果表格:

self.table = QTableWidget()
self.table.setColumnCount(3)
self.table.setHorizontalHeaderLabels(["原目錄名", "新目錄名", "狀態(tài)"])
self.table.setAlternatingRowColors(True)
self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
self.table.setSelectionMode(QAbstractItemView.SingleSelection)
self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeToContents)
self.table.verticalHeader().setVisible(False)
self.table.setShowGrid(False)

三、規(guī)則流水線:如何疊加多個操作

核心點是讓規(guī)則可疊加,并按順序執(zhí)行。

1. 規(guī)則的數(shù)據(jù)結構

在窗口類里維護一個列表:

self.operations = []

每條規(guī)則是一個字典:

{"mode": "prefix", "p1": "2026_", "p2": ""}
{"mode": "replace", "p1": " ", "p2": "_"}
{"mode": "delete", "p1": "test", "p2": ""}

添加規(guī)則時,把當前下拉框和參數(shù)輸入框的值讀出來,做一些校驗后塞進 self.operations

def add_operation(self):
    mode = self.op_combo.currentData()
    p1 = self.param1_edit.text()
    p2 = self.param2_edit.text()

    if mode == "replace" and p1 == "":
        QMessageBox.warning(self, "提示", "“要替換”不能為空")
        return
    if mode in ("prefix", "suffix", "delete") and p1 == "":
        QMessageBox.warning(self, "提示", "參數(shù)不能為空")
        return

    self.operations.append({"mode": mode, "p1": p1, "p2": p2})
    self.refresh_ops_table(select_index=len(self.operations) - 1)
    self.param1_edit.setText("")
    self.param2_edit.setText("")

refresh_ops_tableself.operations 同步到規(guī)則表格里:

def refresh_ops_table(self, select_index=None):
    self.ops_table.setRowCount(0)
    for i, op in enumerate(self.operations):
        row = self.ops_table.rowCount()
        self.ops_table.insertRow(row)
        self.ops_table.setItem(row, 0, QTableWidgetItem(str(i + 1)))
        self.ops_table.setItem(row, 1, QTableWidgetItem(self.mode_to_text(op["mode"])))
        self.ops_table.setItem(row, 2, QTableWidgetItem(op.get("p1", "")))
        self.ops_table.setItem(row, 3, QTableWidgetItem(op.get("p2", "")))

上移 / 下移 / 刪除 / 清空其實就是對 self.operations 做 list 操作,然后調用 refresh_ops_table。

2. 規(guī)則的執(zhí)行:apply_operations

給某個目錄名應用規(guī)則流水線:

def apply_operations(self, name):
    new_name = name
    for op in self.operations:
        new_name = self.get_new_name(op["mode"], new_name, op.get("p1", ""), op.get("p2", ""))
    return new_name

get_new_name 處理具體的四種模式:

def get_new_name(self, mode, name, p1, p2):
    if mode == "prefix":
        if not p1:
            return name
        return p1 + name
    if mode == "suffix":
        if not p1:
            return name
        return name + p1
    if mode == "replace":
        if not p1:
            return name
        return name.replace(p1, p2)
    if mode == "delete":
        if not p1:
            return name
        return name.replace(p1, "")
    return name

預覽時,就對目錄下的每個子目錄名調用一次 apply_operations,得到最終的新名字。

四、安全性:沖突檢測與兩階段重命名

批量改名一定要小心兩件事:

  • 目標名是否合法(Windows 目錄名不能包含 < > : " / \ | ? * 等)
  • 多個目錄是否會改成同一個名字

再進階一點:有可能存在「互換名字」的情況,比如:

  • 原來有 AB
  • 規(guī)則是把 A 改成 B,把 B 改成 A

如果直接 os.rename("A", "B"),后面再改 B -> A 會失敗,因為 B 已經(jīng)存在或者沖突。

1. 合法性和重復的預覽檢查

預覽階段,對每個目錄算完新名字后,會先統(tǒng)計一遍數(shù)量:

new_name_counts = {}
computed = []

for name in dir_names:
    new_name = self.apply_operations(name)
    computed.append((name, new_name))
    new_name_counts[new_name] = new_name_counts.get(new_name, 0) + 1

然后再逐條填到表格里,同時判斷:

if new_name == name:
    continue
if not self.is_valid_dirname(new_name):
    status_item.setText("沖突:非法名稱")
    continue
if new_name_counts.get(new_name, 0) > 1:
    status_item.setText("沖突:目標重復")
    continue

self.rename_tasks.append({"old_path": old_path, "new_path": new_path, "row": row})

is_valid_dirname 簡單過濾非法字符:

def is_valid_dirname(self, name):
    if name is None:
        return False
    if name == "":
        return False
    invalid_chars = set('<>:"/\\|?*')
    return not any(ch in invalid_chars for ch in name)

2. 兩階段重命名:避免互相覆蓋

執(zhí)行重命名時采用了一個「兩階段」策略:

  • 第一階段:把所有要改名的目錄先重命名到一個臨時名字(加上隨機后綴)
  • 第二階段:再從這些臨時名字統(tǒng)一改成目標新名字

這樣就不會出現(xiàn)「A 改成 B,導致原來的 B 被擋住」的問題。

第一階段:

temp_map = {}
stage1_ok = []

for t in valid_tasks:
    old_path = t["old_path"]
    row = t["row"]
    item = self.table.item(row, 2)
    tmp_path = f"{old_path}.__renametmp__{uuid.uuid4().hex}"
    try:
        os.rename(old_path, tmp_path)
        temp_map[tmp_path] = t
        stage1_ok.append(tmp_path)
    except Exception as e:
        msg = f"失敗:{e}"
        item.setText(msg)

第二階段:

for tmp_path in stage1_ok:
    t = temp_map[tmp_path]
    new_path = t["new_path"]
    row = t["row"]
    item = self.table.item(row, 2)
    try:
        os.rename(tmp_path, new_path)
        item.setText("成功")
    except Exception as e:
        item.setText(f"失?。簕e}")
        try:
            os.rename(tmp_path, t["old_path"])
        except Exception:
            pass

這種方式的好處:

  • 可以安全處理「互換名字」等復雜情況
  • 即便第二階段失敗,也可以嘗試把臨時目錄改回去,盡量保持原狀

五、讓界面更好看一點:簡單的 PyQt5 美化

界面美化主要從三個方面入手:

  • 使用 Qt 的 Fusion 風格
  • 統(tǒng)一字體、背景、卡片式分組
  • 按鈕和表格的細節(jié)樣式

設置 Fusion 風格和字體:

def apply_theme(self):
    QApplication.setStyle(QStyleFactory.create("Fusion"))
    font = QFont()
    font.setPointSize(10)
    QApplication.setFont(font)
    self.setStyleSheet(
        """
        QMainWindow { background: #f5f7fb; }
        QGroupBox {
            background: #ffffff;
            border: 1px solid #e2e8f0;
            border-radius: 10px;
            margin-top: 8px;
        }
        QGroupBox::title {
            subcontrol-origin: margin;
            left: 12px;
            padding: 0 6px;
            color: #334155;
            font-weight: 600;
        }
        QLabel { color: #334155; }
        QLineEdit, QComboBox {
            background: #ffffff;
            border: 1px solid #cbd5e1;
            border-radius: 8px;
            padding: 7px 10px;
            min-height: 20px;
        }
        QLineEdit:focus, QComboBox:focus { border: 1px solid #4f46e5; }
        QPushButton {
            background: #4f46e5;
            color: #ffffff;
            border: none;
            border-radius: 10px;
            padding: 8px 14px;
            font-weight: 600;
        }
        QPushButton:hover { background: #4338ca; }
        QPushButton:pressed { background: #3730a3; }
        QPushButton:disabled { background: #94a3b8; color: #f8fafc; }
        QTableWidget {
            background: #ffffff;
            border: 1px solid #e2e8f0;
            border-radius: 10px;
            selection-background-color: #e0e7ff;
            selection-color: #0f172a;
            gridline-color: transparent;
        }
        QHeaderView::section {
            background: #f1f5f9;
            color: #334155;
            border: none;
            padding: 8px 10px;
            font-weight: 600;
        }
        QTableWidget::item { padding-left: 8px; padding-right: 8px; }
        QStatusBar { background: transparent; color: #475569; }
        """
    )

同時,用 QStatusBar 提示當前狀態(tài),比如:

  • 預覽完成:可執(zhí)行多少條重命名
  • 新增了幾條規(guī)則
self.setStatusBar(self.statusBar())
self.statusBar().showMessage("選擇一個目錄后點擊“預覽”,確認無誤再執(zhí)行重命名")

六、運行結果

七、使用 PyInstaller 打包成單文件 EXE

工具完成之后,為了方便在沒有 Python 環(huán)境的電腦上使用,需要打包成 EXE。這里用的是 PyInstaller。

假設目錄結構:

D:\測試\Github項目\61-目錄批量改名\
  ├─ renamedir.py
  ├─ 重命名.png
  └─ ...

1. 把 PNG 轉成 ICO(用于 EXE 圖標)

PyInstaller 的 --icon 參數(shù)需要 .ico 文件,所以先用 Pillow 轉一下:

cd /d "D:\測試\Github項目\61-目錄批量改名"

python -m pip install pillow

python -c "from PIL import Image; Image.open('重命名.png').save('重命名.ico')"

這樣目錄下就會多出一個 重命名.ico。

2. 打包命令

在同一個目錄下執(zhí)行:

pyinstaller -F -w --clean ^
  --name "renamedir" ^
  --icon "重命名.ico" ^
  "renamedir.py"

參數(shù)含義:

  • -F:單文件 EXE
  • -w:不彈出控制臺窗口
  • --clean:打包時清理緩存
  • --name "renamedir":生成的 exe 名叫 renamedir.exe
  • --icon "重命名.ico":給 exe 加上自定義圖標

打包完成后,會生成:

D:\測試\Github項目\61-目錄批量改名\
  ├─ build\
  ├─ dist\
  │   └─ renamedir.exe
  └─ renamedir.spec

雙擊 dist\renamedir.exe 就可以像普通 Windows 程序一樣使用了。

八、總結與可擴展方向

這個小工具本質上是一個「批量字符串處理器 + 可視化預覽」,換到別的場景也非常通用:

  • 把「目錄名」換成「文件名」,立即變成批量改文件名工具
  • 把規(guī)則擴展成:
    • 大小寫轉換(全部大寫、全部小寫、首字母大寫)
    • 正則替換(使用 re.sub
    • 基于數(shù)字的自動編號等

如果繼續(xù)擴展,可以考慮:

  • 增加「遞歸子目錄」選項(深度遍歷)
  • 增加「撤銷」「導出重命名日志」功能
  • 把規(guī)則保存/加載為配置文件(比如 json),方便復用

以上就是Python結合PyQt5編寫一個批量目錄重命名工具并打包成EXE的詳細內容,更多關于Python批量目錄重命名的資料請關注腳本之家其它相關文章!

相關文章

  • odoo字段訪問控制的操作方法

    odoo字段訪問控制的操作方法

    在 Odoo 中,可以通過幾種方式實現(xiàn)字段的訪問控制?0c;包括通過模型安全規(guī)則、記錄規(guī)則和字段屬性來限制字段的訪問,這篇文章主要介紹了odoo字段訪問控制的相關操作,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • Python3多目標賦值及共享引用注意事項

    Python3多目標賦值及共享引用注意事項

    這篇文章主要介紹了Python3多目標賦值及共享引用注意事項,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-05-05
  • PyCharm使用最多也最常用默認快捷鍵分享

    PyCharm使用最多也最常用默認快捷鍵分享

    這篇文章主要介紹了PyCharm使用最多也最常用默認快捷鍵,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • NumPy的hstack函數(shù)詳細教程

    NumPy的hstack函數(shù)詳細教程

    np.hstack()是NumPy庫中用于水平堆疊數(shù)組的函數(shù),本文就來介紹一下NumPy的hstack函數(shù)的使用,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2026-01-01
  • Tensorflow的可視化工具Tensorboard的初步使用詳解

    Tensorflow的可視化工具Tensorboard的初步使用詳解

    這篇文章主要介紹了Tensorflow的可視化工具Tensorboard的初步使用詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • Windows+Mac通用Python詳細安裝教程及避坑指南(新手必看!)

    Windows+Mac通用Python詳細安裝教程及避坑指南(新手必看!)

    Python安裝包雖然版本不同,但安裝過程都是差不多的,這篇文章主要介紹了Windows+Mac通用Python詳細安裝教程及避坑指南的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2026-05-05
  • linux mint中搜狗輸入法導致pycharm卡死的問題

    linux mint中搜狗輸入法導致pycharm卡死的問題

    這篇文章主要介紹了linux mint中搜狗輸入法導致pycharm卡死的問題,這篇文章給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • pymysql的安裝以及操作實戰(zhàn)指南

    pymysql的安裝以及操作實戰(zhàn)指南

    這篇文章主要給大家介紹了關于pymysql的安裝以及操作的相關資料,pymsql是Python中操作MySQL的模塊,其使用方法和MySQLdb幾乎相同,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • Django REST framework 限流功能的使用

    Django REST framework 限流功能的使用

    DRF常用功能的案例基本用法都有講解,關于限流(Throttling)這個功能其實在真實的業(yè)務場景中能真正用到的其實不算多。今天說這個話題其實一方面是討論功能,另一方面也是希望換個角度去審視我們的開發(fā)過程,希望大家可以在使用DRF功能的同時,也了解一下功能背后的實現(xiàn)
    2021-06-06
  • 使用Python在Excel工作表中添加、編輯和刪除批注

    使用Python在Excel工作表中添加、編輯和刪除批注

    在數(shù)據(jù)分析和報表制作過程中,Excel 批注(Comment)是一種非常實用的功能,用于對特定單元格進行補充說明、添加備注或記錄審核意見,本文將使用?Free Spire.XLS for Python?展示如何在 Excel 工作表中添加、編輯和刪除批注,需要的朋友可以參考下
    2026-04-04

最新評論

北辰区| 潜江市| 钦州市| 丰都县| 太和县| 沂水县| 鲁山县| 屏东县| 龙胜| 五家渠市| 栾川县| 克什克腾旗| 杂多县| 石渠县| 怀来县| 普兰店市| 清徐县| 张家界市| 米泉市| 塔河县| 江永县| 呈贡县| 巧家县| 安塞县| 永福县| 夹江县| 剑河县| 成都市| 华蓥市| 忻城县| 察隅县| 礼泉县| 奉新县| 安远县| 桦南县| 定州市| 息烽县| 海安县| 大同县| 县级市| 灌阳县|