You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQT拖拽重排图片缩略图及批量重命名技术咨询

解决方案

PyQt/PySide 最优方案:QListWidget

QListWidget是实现你需求最简便的组件,无需手动计算坐标或重绘,内置网格布局和拖拽重排支持:

  • 开启网格显示:通过setViewMode(QListWidget.IconMode)和setFlow(QListWidget.LeftToRight)让列表项以网格形式排列,还可通过setIconSize()自定义缩略图尺寸。
  • 启用拖拽重排:只需配置setDragDropMode(QListWidget.InternalMove)和setDefaultDropAction(Qt.MoveAction),就能让用户拖拽调整项的顺序,框架会自动处理布局更新。
  • 绑定图片:每个列表项用QListWidgetItem的setIcon()方法设置缩略图,通过QPixmap加载并缩放图片即可。

核心代码示例

from PyQt5.QtWidgets import (QApplication, QListWidget, QListWidgetItem, 
                             QWidget, QVBoxLayout, QPushButton)
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtCore import Qt
import os

class ImageRenamer(QWidget):
    def __init__(self, image_paths):
        super().__init__()
        self.image_paths = image_paths
        self.init_ui()

    def init_ui(self):
        layout = QVBoxLayout()
        
        # 初始化网格列表组件
        self.list_widget = QListWidget()
        self.list_widget.setViewMode(QListWidget.IconMode)
        self.list_widget.setFlow(QListWidget.LeftToRight)
        self.list_widget.setIconSize(Qt.QSize(120, 120))
        # 启用内部拖拽重排
        self.list_widget.setDragDropMode(QListWidget.InternalMove)
        self.list_widget.setDefaultDropAction(Qt.MoveAction)
        
        # 添加图片项
        for path in self.image_paths:
            pixmap = QPixmap(path).scaled(120, 120, Qt.KeepAspectRatio)
            item = QListWidgetItem(QIcon(pixmap), os.path.basename(path))
            item.setData(Qt.UserRole, path)  # 存储原路径
            self.list_widget.addItem(item)
        
        # 重命名按钮
        rename_btn = QPushButton("按顺序重命名")
        rename_btn.clicked.connect(self.rename_images)
        
        layout.addWidget(self.list_widget)
        layout.addWidget(rename_btn)
        self.setLayout(layout)
        self.setWindowTitle("图片批量重命名")

    def rename_images(self):
        # 获取排序后的图片路径
        sorted_paths = []
        for i in range(self.list_widget.count()):
            item = self.list_widget.item(i)
            sorted_paths.append(item.data(Qt.UserRole))
        
        # 执行重命名逻辑
        for idx, path in enumerate(sorted_paths):
            dir_name = os.path.dirname(path)
            ext = os.path.splitext(path)[1]
            new_name = os.path.join(dir_name, f"image_{idx+1}{ext}")
            os.rename(path, new_name)

if __name__ == "__main__":
    app = QApplication([])
    # 替换为你的图片路径列表
    img_paths = ["img1.jpg", "img2.png", "img3.jpeg"]
    window = ImageRenamer(img_paths)
    window.show()
    app.exec_()

其他Python框架方案:Flet

如果你想尝试更轻量化的框架,Flet的GridView结合Draggable和DragTarget组件可以快速实现拖拽重排的网格布局,代码量极少,无需复杂的Qt概念:

核心代码示例

import flet as ft
import os

def main(page: ft.Page):
    page.title = "图片批量重命名"
    image_paths = ["img1.jpg", "img2.png", "img3.jpeg"]  # 替换为你的图片路径
    items = []

    def drag_will_accept(e):
        e.data = e.src_id
        e.control.update()

    def drag_accept(e):
        # 交换拖拽项和目标项的位置
        src_idx = int(e.src_id.split("_")[-1])
        target_idx = int(e.control.data)
        items[src_idx], items[target_idx] = items[target_idx], items[src_idx]
        refresh_grid()

    def refresh_grid():
        grid.controls.clear()
        for idx, path in enumerate(items):
            grid.controls.append(
                ft.DragTarget(
                    data=str(idx),
                    on_will_accept=drag_will_accept,
                    on_accept=drag_accept,
                    content=ft.Draggable(
                        group="image",
                        content=ft.Image(
                            src=path,
                            width=120,
                            height=120,
                            fit=ft.ImageFit.COVER
                        ),
                        content_when_dragged=ft.Image(
                            src=path,
                            width=100,
                            height=100,
                            fit=ft.ImageFit.COVER
                        ),
                        feedback=ft.Image(
                            src=path,
                            width=100,
                            height=100,
                            fit=ft.ImageFit.COVER
                        ),
                        id=f"drag_{idx}"
                    )
                )
            )
        page.update()

    def rename_images(e):
        for idx, path in enumerate(items):
            dir_name = os.path.dirname(path)
            ext = os.path.splitext(path)[1]
            new_name = os.path.join(dir_name, f"image_{idx+1}{ext}")
            os.rename(path, new_name)
        page.snack_bar = ft.SnackBar(ft.Text("重命名完成!"))
        page.snack_bar.open = True
        page.update()

    items = image_paths.copy()
    grid = ft.GridView(
        expand=True,
        runs_count=3,
        max_extent=150,
        spacing=10,
        run_spacing=10,
    )
    refresh_grid()

    page.add(
        grid,
        ft.ElevatedButton("按顺序重命名", on_click=rename_images)
    )

if __name__ == "__main__":
    ft.app(target=main)

内容的提问来源于stack exchange,提问作者Lenoba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 22:20:29