文字标签修改pyqt5小工具

该博客介绍了如何使用PyQt5创建一个图像标注和管理的软件,包括打开文件夹、浏览图片、图片旋转、标记删除、确认删除等功能。程序实现了图片的上一张和下一张切换,以及180度旋转。此外,还提供了修改图片标签、跳转指定索引和批量处理删除的功能,帮助用户高效地进行图像标注工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

untitled.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

import cv2
from PyQt5.QtWidgets import QLineEdit, QWidget, QPushButton,QLabel,QFileDialog,QMessageBox
from PyQt5.QtCore import QRect,QMetaObject,QCoreApplication,Qt
from PyQt5.QtGui import QPixmap,QTransform,QFont
import os
import shutil

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(992, 772)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.aotu_save = True

        ##last pic button
        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QRect(420, 530, 93, 28))
        self.pushButton.setObjectName("pushButton")
        self.pushButton.clicked.connect(self.last_pic)

        ##next pic button
        self.pushButton_2 = QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QRect(620, 530, 93, 28))
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_2.clicked.connect(self.next_pic)
        self.pushButton_2.setShortcutEnabled(True)

        ##open folder button
        self.open_file = QPushButton(self.centralwidget)
        self.open_file.setGeometry(QRect(110, 530, 93, 28))
        self.open_file.setObjectName("open_file")
        self.open_file.clicked.connect(self.open)

        ##rot180  button
        self.rot180 = QPushButton(self.centralwidget)
        self.rot180.setGeometry(QRect(270, 530, 93, 28))
        self.rot180.setObjectName("rot180_pic")
        self.rot180.clicked.connect(self.rot180_pic)

        ##mark  button
        self.mark_button = QPushButton(self.centralwidget)
        self.mark_button.setGeometry(QRect(800, 530, 120, 28))
        self.mark_button.setObjectName("delete")
        self.mark_button.clicked.connect(self.mark_delete_pic)

        ##delete  button
        self.delete_button = QPushButton(self.centralwidget)
        self.delete_button.setGeometry(QRect(800, 600, 120, 28))
        self.delete_button.setObjectName("delete")
        self.delete_button.clicked.connect(self.delete_pic)


        ## res modify  button
        self.modify = QPushButton(self.centralwidget)
        self.modify.setGeometry(QRect(500, 310, 93, 50))
        self.modify.setObjectName("modify")
        self.modify.clicked.connect(self.modify_res)

        ## index jump button
        self.jump = QPushButton(self.centralwidget)
        self.jump.setGeometry(QRect(250, 420, 93, 50))
        self.jump.setObjectName("jump")
        self.jump.clicked.connect(self.jump_index)

        ### res Edit
        self.init_font()
        self.plate_label_input = QLineEdit(self)
        self.plate_label_input.setGeometry(QRect(110, 310, 300, 50))
        self.plate_label_input.setFont(self.font)

        ### index Edit
        self.plate_index_input = QLineEdit(self)
        self.plate_index_input.setGeometry(QRect(110, 420, 100, 50))
        self.plate_index_input.setFont(self.font)


        MainWindow.setCentralWidget(self.centralwidget)
        self.label = QLabel(self.centralwidget)
        # self.label.setGeometry(QtCore.QRect(230, 80, 72, 15))
        self.label.setObjectName("label")
        self.label_2 = QLabel(self.centralwidget)
        self.label_2.setGeometry(QRect(40, 275, 72, 15))
        self.label_2.setObjectName("label_2")

        self.label_3 = QLabel(self.centralwidget)
        self.label_3.setGeometry(QRect(45, 435, 72, 15))
        self.label_3.setObjectName("label_3")


        self.label_4 = QLabel(self.centralwidget)
        self.label_4.setGeometry(QRect(500, 50, 1000, 20))
        self.label_4.setObjectName("label_4")


        self.label_info = QLabel(self.centralwidget)
        self.label_info.setGeometry(QRect(50, 600, 550, 120))
        self.label_info.setObjectName("label_info")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "上一张图片"))
        self.pushButton.setShortcut(_translate("MainWindow", "A"))
        self.pushButton_2.setText(_translate("MainWindow", "下一张图片"))
        self.pushButton_2.setShortcut(_translate("MainWindow", "D"))
        self.open_file.setText(_translate("MainWindow", "打开"))
        self.open_file.setShortcut(_translate("MainWindow", "ctrl+o"))
        self.modify.setText(_translate("MainWindow", "修改"))
        self.modify.setShortcut(_translate("MainWindow", "ctrl+s"))
        self.jump.setText(_translate("MainWindow", "跳转"))
        self.rot180.setText(_translate("MainWindow", "图片旋转180"))
        self.mark_button.setText(_translate("MainWindow", "标记图片为删除"))
        self.delete_button.setText(_translate("MainWindow", "确认删除"))
        self.rot180.setShortcut(_translate("MainWindow", "space"))
        self.label.setText(_translate("MainWindow", "这是图片"))
        self.label_2.setText(_translate("MainWindow", "这是路径"))
        self.label_3.setText(_translate("MainWindow", "图片索引"))
        self.label_info.setText(_translate("MainWindow", "*图片旋转快捷键为空格键\n*上一张快捷键为A\n*下一张快捷键为D\n*打开快捷键为Ctrl+O\n"
                                                         "*修改快捷键为Ctrl+S\n"
                                                         "*图片标记为删除不会忙着先删除图片哈,先放到同目录下的trash_bin中\n"
                                                         "*点击确认删除会删除文件夹中标记过的图片及其在txt中的标签,并清空trash_bin"))



    def open(self):
        self.file_path =  QFileDialog.getExistingDirectory(self, '选择文文件夹', '/')
        self.read_folder()

    def read_folder(self):
        self.trash_bin = self.file_path + '/trash_bin'
        if self.file_path:
            filenames = os.listdir(self.file_path)
            self.file_list = [self.file_path+'/'+i for i in filenames if not i.endswith('txt') and not i == 'trash_bin']
            self.res_path = [self.file_path+'/'+i for i in filenames if i.endswith('txt')]
            if self.init_res_dit():
                self.index = 0
                self.img_length = len(self.file_list)
                self.addPic()

    def init_res_dit(self):
        self.res_dict={}
        if len(self.res_path) == 0:
            msg_box = QMessageBox(QMessageBox.Warning, 'Warning', 'there is no text file!please rechoose the folder ')
            msg_box.exec_()
            return False
        else:
            with open(self.res_path[0]) as f:
                datas = f.readlines()
                for item in datas:
                    tmp = item.strip().split(' ')
                    self.res_dict[tmp[0]]  = tmp[1]
            return True



    def addPic(self):
        path = self.file_list[self.index]
        print(path)
        print(self.index)
        img = cv2.imread(path)
        h,w,_ = img.shape
        self.current_fileName = path.split('/')[-1]
        if h and w:
            self.pix = QPixmap(path)
            self.label.setGeometry(0,0,400,266)
            self.label.setPixmap(self.pix)
            self.label.setScaledContents(True)
            self.label_2.setText('图片路径:'+path)
            self.label_2.setAlignment(Qt.AlignCenter)
            self.label_2.adjustSize()
            self.plate_index_input.setText(str(self.index))
            self.plate_label_input.setText(self.res_dict[self.current_fileName])
            self.label_4.setText(f'加油 还有 {self.img_length-self.index-1} 张图片~~~~')



    def last_pic(self):
        file_path = getattr(self, "file_path", None)
        if file_path:
            self.index -=1
            if self.index < 0:
                self.index = self.img_length + self.index
            self.addPic()
        # msg_box = QMessageBox(QMessageBox.Warning, 'Warning', 'no ')
        # msg_box.exec_()

    def next_pic(self):
        file_path = getattr(self, "file_path", None)
        if file_path:
            self.index += 1
            if self.index>=self.img_length:
                self.index = 0
            self.addPic()

    def rot180_pic(self):
        file_path = getattr(self, "file_path", None)
        if file_path:
            transform = QTransform()
            transform.rotate(180)
            self.pix = self.pix.transformed(transform)
            self.label.setGeometry(0, 0, 400, 266)
            self.label.setPixmap(self.pix)
            self.label.setScaledContents(True)


    def init_font(self):
        self.font = QFont()
        self.font.setPointSize(16)

    def modify_res(self):
        file_path = getattr(self, "file_path", None)
        if file_path :
            changed_str = self.plate_label_input.text()
            self.res_dict[self.current_fileName] = changed_str
            if self.aotu_save:
                self.save_resFile()


    def save_resFile(self):
        with open(self.res_path[0],mode='w',encoding='utf8') as f:
            for filename in self.res_dict:
                label = self.res_dict[filename]
                f.write(filename + ' ' + label + '\n')

    def jump_index(self):
        file_path = getattr(self, "file_path", None)
        if file_path :
            tmp = self.plate_index_input.text()
            flag = True
            for i in tmp:
                if i not in '1234567890':
                    flag = False
                    break
            if flag:
                self.index = int(tmp)
                self.addPic()


    def delete_pic(self):
        file_path = getattr(self, "file_path", None)
        if file_path:
            delete_li = os.listdir(self.trash_bin)
            for i in delete_li:
                os.remove(self.file_path+'/'+i)
            shutil.rmtree(self.trash_bin)
            with open(self.res_path[0], mode='w', encoding='utf8') as f:
                for filename in self.res_dict:
                    if filename not in delete_li:
                        label = self.res_dict[filename]
                        f.write(filename + ' ' + label + '\n')

            self.read_folder()


    def mark_delete_pic(self):
        file_path = getattr(self, "file_path", None)
        if file_path:
            if not os.path.exists(self.trash_bin):
                os.mkdir(self.trash_bin)
            shutil.copy(self.file_path+'/'+self.current_fileName,self.trash_bin+'/'+self.current_fileName)

main.py

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from untitled import *

class Example(QMainWindow,Ui_MainWindow):

    def __init__(self):
        super().__init__()
        self.setupUi(self)  ##界面绘制



if __name__ == '__main__':
    ##创建应用对象
    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

界面

在这里插入图片描述
用pyinstaller打包成exe的命令,打包出来的exe比较大有80几M
pyinstaller -F -c main.py
界面的话先用QT Designer初步弄的 生成.ui文件 再用工具转成.py文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值