前提:因为工作需要,需要重复的改同样的文件名和复制粘贴文件夹,所以使用python写了修改文件名和复制文件夹的小工具.为了工具的可使用化可方便,花了一周时间学习wxpython书写成一个图形界面软件.并使用pyinstaller打包成windows运行的exe文件
准备工作
环境:windows10 python v3.8 wxpython v4.1
下载wxpython包:pip install wxpython or pip install -i https://pypi.douban.com/simple/ wxpython
工具:pycharm V2019.3 wxFormBuider V3.5
wxFrombuider下载:链接:https://pan.baidu.com/s/1SPYCn1rbLx1g8EKVbrXT9g
提取码:e7yi
pycharm:大家自行百度吧,实在太多了,有不行的再留言我
窗口程序搭建
创建一个窗口程序
创建一个窗口项目
进入wxFromBuider后点击froms,和frame创建一个frame,然后点击layout选择布局(注意,这里的布局可以嵌套使用,也只有有布局以后才能在wxFromBuider里面放置组件)
然后在窗口里面添加组件
这里我添加了两个组件,一个文本框和按钮
给按钮添加事件
窗口程序创建好以后程序已经完成一半,接下来就是给各个组件添加触发事件,
在everts里面为你的组件添加触发事件
生成python代码
上面的图只是我做的一个示列,但一系列组件和事件添加完成以后,生成python代码,在项目界面按F8生成代码,选择python进去复制代码
代码报错及修改
将代码复制到pycharm里面后将下面代码加入到我们复制的代码最后
app = wx.App()
#这里的类名根据你生成的类名定义
frm = MyFrame1(None)
frm.Show()
app.MainLoop()
所有代码为:
###########################################################################
## Python code generated with wxFormBuilder (version Jun 5 2014)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
###########################################################################
## Class MyFrame1
###########################################################################
class MyFrame1(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition,
size=wx.Size(500, 300), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
bSizer1 = wx.BoxSizer(wx.VERTICAL)
self.m_textCtrl1 = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
bSizer1.Add(self.m_textCtrl1, 0, wx.ALL, 5)
self.m_button1 = wx.Button(self, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer1.Add(self.m_button1, 0, wx.ALL, 5)
self.SetSizer(bSizer1)
self.Layout()
self.Centre(wx.BOTH)
# Connect Events
self.m_button1.Bind(wx.EVT_BUTTON, self.chick_me)
def __del__(self):
pass
# Virtual event handlers, overide them in your derived class
def chick_me(self, event):
event.Skip()
app = wx.App()
frm = MyFrame1(None)
frm.Show()
app.MainLoop()
运行结果为:
做一个消息提示吧
用刚刚的代码,在按键事件中写一个事件,当按钮按下后,读取文本框数值,并用消息框弹出
代码如下:
def chick_me(self, event):
"""
按键按下事件发生
:param event:
:return:
"""
# 获取文本框输入的数值
data_txt=self.m_textCtrl1.GetValue()
#创建一个消息对话框
dlg = wx.MessageDialog(None, data_txt, '提示', wx.YES_NO | wx.ICON_QUESTION)
# 显示消息对话框并获取返回值
result = dlg.ShowModal()
if result == wx.ID_YES:
# 用户点击确认
pass
else:
# 用户点击取消
pass
# 事件结束
event.Skip()
逻辑程序书写
个人建议将逻辑程序和窗口程序分开,将逻辑程序当成一个包导入,前段提供必要的字段和数据,后端实现数据处理并返回数据,由前端输出
前端事件函数做简单数据处理与逻辑处理后将数据交给逻辑模块干活
#file_nameis event_processing.py
def Change_name_GO(self, event):
"""
文件改名事件
读取文件文本框内容,整理发送给逻辑模块处理事件
:param event:
:return:
"""
self.Tips_views.Clear()
default_name = self.default_name_txt.GetValue()
nwe_file_name_txt = self.nwe_file_name_txt.GetValue()
name_mak=self.name_mak.GetValue()
if name_mak:
msg = "你将要把文件名为{}的文件修为{},且前面添加序号,确定吗?".format(default_name, nwe_file_name_txt)
else:
msg = "你将要把文件名为{}的文件修为{},且前面不添加添加序号,确定吗?".format(default_name, nwe_file_name_txt)
dlg = wx.MessageDialog(None, msg, '提示', wx.YES_NO | wx.ICON_QUESTION)
result = dlg.ShowModal()
if result == wx.ID_YES:
txt = event_processing.Modify_file_name(Default_name=default_name, keyword=nwe_file_name_txt,name_mak=name_mak).start()
msg = ""
for i in txt:
msg += i
self.Tips_views.SetValue(msg)
else:
pass
dlg.Destroy()
event.Skip()
最后干货来了,有教程也有代码
import os, shutil
import re
class Modify_file_name:
def __init__(self, Default_name, keyword, name_mak):
self.filePath = os.getcwd()
self.keyword = keyword
self.Default_name = Default_name
self.name_mak = name_mak
self.file_number = None
def start(self):
files_OK = 0
files_error = 0
for current_path, Subpath, files in os.walk(self.filePath):
if self.Default_name in files:
for item in files:
if self.name_mak:
if len(item.split(r".")[0]) < 5:
number = item.split(r'.')[0]
used_name = current_path + r"\{}".format(self.Default_name)
new_name = current_path + r"\{}{}".format(number, self.keyword)
try:
os.rename(used_name, new_name)
files_OK += 1
fplder = current_path.split("\\")[-1]
yield "%s文件%s重命名成功,新的文件名为%s\n" % (fplder,
os.path.split(used_name)[-1],
os.path.split(new_name)[-1])
break
except Exception as e:
files_error += 1
yield "重命名文件失败,原因为{},路径为:{}\n".format(e, used_name)
break
else:
used_name = current_path + r"\{}".format(self.Default_name)
new_name = current_path + r"\{}".format(self.keyword)
try:
os.rename(used_name, new_name)
files_OK += 1
fplder = current_path.split("\\")[-1]
yield "%s文件%s重命名成功,新的文件名为%s\n" % (fplder,os.path.split(used_name)[-1], os.path.split(new_name)[-1])
break
except Exception as e:
files_error += 1
yield "重命名文件失败,原因为{},路径为:{}\n".format(e, used_name)
break
else:
yield "文件重名完毕,成功{}个,失败{}个\n".format(files_OK, files_error)
class Copy_folder:
def __init__(self, key_name, number, str_split):
self.key_name = key_name
self.number = number
self.str_split = str_split
self.path_list = []
self.current_directory = os.getcwd()
for current_path, Subpath, files in os.walk(os.getcwd()):
for file in Subpath:
self.path_list.append(current_path + r"\{}".format(file))
break
def create_folder(self):
folder_OK = 0
folder_error = 0
existence_folder_number = 0
while self.number:
try:
existence_folder = False
for i in self.path_list:
name = self.key_name[:-1] + str(self.number)
# print(type(i),i)
if bool(re.search(name, i, re.IGNORECASE)):
self.number -= 1
existence_folder = True
break
if existence_folder:
existence_folder_number += 1
continue
os.mkdir(self.key_name[:-1] + str(self.number))
self.path_list.append(os.getcwd() + r"\{}".format(self.key_name[:-1] + str(self.number)))
folder_OK += 1
yield '创建文件夹:{}成功\n'.format(self.key_name[:-1] + str(self.number))
self.number -= 1
except Exception as e:
self.number -= 1
folder_error += 1
print(e)
yield '创建文件夹:{}失败,原因如下:{}\n'.format(self.key_name[:-1] + str(self.number + 1), e)
yield '创建文件夹完成,成功{}个,失败{}个,已存在文件夹{}个,开始复制文件\n'.format(folder_OK, folder_error, existence_folder_number)
def copy_files(self):
copy_file_OK = 0
copy_file_error = 0
for current_path, _, files in os.walk(self.path_list.pop(0)):
for file in files:
for item_path in self.path_list:
if self.key_name in item_path:
break
yield '正在复制文件{} 到{}\n'.format(file, item_path)
try:
shutil.copy(current_path + r"\{}".format(file), item_path)
yield '文件:{}复制完成\n'.format(file)
copy_file_OK += 1
except Exception as e:
yield '文件复制失败,原因如下:\n{}'.format(e)
copy_file_error += 1
yield '文件复制完毕,成功{}个,失败{}个\n'.format(copy_file_OK, copy_file_error)
def start(self):
msg1 = self.create_folder()
yield msg1
msg2 = self.copy_files()
yield msg2
if __name__ == '__main__':
Default_name = input("请输入默认文件名:")
# while True:
# keyword = input("请输入新文件编号后缀:(如:#x+100g)")
# if keyword != "":
# break
# if Default_name == "":
# ll = Modify_file_name(keyword=keyword)
# else:
# ll = Modify_file_name(keyword=keyword, Default_name=Default_name)
# ll.start()
#
Default_name1 = int(input("qing"))
ll = Copy_folder(Default_name, Default_name1, "")
lli = ll.start()
# for l in lli[0]:
# print(l)
# for l in lli[1]:
# print(l)
#
窗口程序代码
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Jun 5 2014)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
import event_processing
file_name = 1000
###########################################################################
## Class File_name_modification
###########################################################################
class File_name_modification(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, id=file_name, title=u"文件名修改工具", pos=wx.DefaultPosition, size=wx.Size(850, 600),
style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL, name=u"file_name_1")
icon = wx.Icon(r'C:\Users\xxhaa\Desktop\file_name\dist\hhyq.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(icon)
self.SetSizeHints(wx.DefaultSize, wx.Size(1920, 1024))
self.SetForegroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT))
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
gSizer1 = wx.GridSizer(0, 0, 0, 0)
sbSizer31 = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, wx.EmptyString), wx.VERTICAL)
gSizer3 = wx.GridSizer(10, 2, 0, 0)
self.default_name = wx.StaticText(self, wx.ID_ANY, u"默认名字", wx.DefaultPosition, wx.DefaultSize, 0)
self.default_name.Wrap(-1)
gSizer3.Add(self.default_name, 1, wx.ALL | wx.EXPAND, 5)
self.default_name_txt = wx.TextCtrl(self, wx.ID_ANY, u"file_name1", wx.DefaultPosition, wx.DefaultSize, 0)
gSizer3.Add(self.default_name_txt, 1, wx.ALL | wx.EXPAND, 5)
self.nwe_file_name = wx.StaticText(self, wx.ID_ANY, u"新文件名", wx.DefaultPosition, wx.DefaultSize, 0)
self.nwe_file_name.Wrap(-1)
gSizer3.Add(self.nwe_file_name, 1, wx.ALL | wx.EXPAND, 5)
self.nwe_file_name_txt = wx.TextCtrl(self, wx.ID_ANY, u"#x+100.txt", wx.DefaultPosition, wx.DefaultSize, 0)
gSizer3.Add(self.nwe_file_name_txt, 0, wx.ALL | wx.EXPAND, 5)
self.name_mak = wx.CheckBox(self, wx.ID_ANY, u"文件名序号", wx.DefaultPosition, wx.DefaultSize, 0)
gSizer3.Add(self.name_mak, 1, wx.ALL | wx.EXPAND, 5)
self.Change_name = wx.Button(self, wx.ID_ANY, u"确认修改", wx.DefaultPosition, wx.DefaultSize, 0)
gSizer3.Add(self.Change_name, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND | wx.ALL, 5)
self.m_staticText71 = wx.StaticText(self, wx.ID_ANY, u"复制文件夹名字", wx.DefaultPosition, wx.DefaultSize, 0)
self.m_staticText71.Wrap(-1)
gSizer3.Add(self.m_staticText71, 1, wx.EXPAND | wx.ALL, 5)
self.m_textCtrl5 = wx.TextCtrl(self, wx.ID_ANY, u"COMM1", wx.DefaultPosition, wx.DefaultSize, 0)
gSizer3.Add(self.m_textCtrl5, 1, wx.ALL | wx.EXPAND, 5)
self.m_staticText8 = wx.StaticText(self, wx.ID_ANY, u"复制文件夹个数", wx.DefaultPosition, wx.DefaultSize, 0)
self.m_staticText8.Wrap(-1)
gSizer3.Add(self.m_staticText8, 1, wx.EXPAND | wx.ALL, 5)
self.m_textCtrl4 = wx.TextCtrl(self, wx.ID_ANY, u"5", wx.DefaultPosition, wx.DefaultSize, 0)
gSizer3.Add(self.m_textCtrl4, 1, wx.EXPAND | wx.ALL, 5)
self.m_staticText9 = wx.StaticText(self, wx.ID_ANY, u"递增间隔符", wx.DefaultPosition, wx.DefaultSize, 0)
self.m_staticText9.Wrap(-1)
gSizer3.Add(self.m_staticText9, 1, wx.EXPAND | wx.ALL, 5)
self.m_textCtrl6 = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
gSizer3.Add(self.m_textCtrl6, 1, wx.EXPAND | wx.ALL, 5)
gSizer3.AddSpacer(0)
self.copy_file = wx.Button(self, wx.ID_ANY, u"确认复制", wx.DefaultPosition, wx.DefaultSize, 0)
gSizer3.Add(self.copy_file, 0, 0, 5)
sbSizer31.Add(gSizer3, 1, wx.EXPAND | wx.FIXED_MINSIZE, 1)
gSizer1.Add(sbSizer31, 1, wx.EXPAND, 5)
sbSizer3 = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, wx.EmptyString), wx.VERTICAL)
self.m_staticText7 = wx.StaticText(self, wx.ID_ANY, u"信息显示区域:", wx.DefaultPosition, wx.DefaultSize, 0)
self.m_staticText7.Wrap(-1)
self.m_staticText7.SetForegroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT))
sbSizer3.Add(self.m_staticText7, 0, wx.ALL, 5)
self.Tips_views = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,style=((wx.TE_MULTILINE | wx.TE_DONTWRAP | wx.TE_READONLY | wx.TE_WORDWRAP)))
self.Tips_views.SetForegroundColour(wx.Colour(128, 255, 0))
self.Tips_views.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
sbSizer3.Add(self.Tips_views, 1, wx.ALL | wx.EXPAND, 5)
gSizer1.Add(sbSizer3, 1, wx.EXPAND, 5)
self.SetSizer(gSizer1)
self.Layout()
self.Centre(wx.BOTH)
# Connect Events
self.default_name_txt.Bind(wx.EVT_TEXT, self.default_name_txtOnText)
self.Change_name.Bind(wx.EVT_BUTTON, self.Change_name_GO)
self.copy_file.Bind(wx.EVT_BUTTON, self.copy_files)
def __del__(self):
pass
# Virtual event handlers, overide them in your derived class
def Change_name_GO(self, event):
"""
文件改名事件
读取文件文本框内容,整理发送给逻辑模块处理事件
:param event:
:return:
"""
self.Tips_views.Clear()
default_name = self.default_name_txt.GetValue()
nwe_file_name_txt = self.nwe_file_name_txt.GetValue()
name_mak=self.name_mak.GetValue()
if name_mak:
msg = "你将要把文件名为{}的文件修为{},且前面添加序号,确定吗?".format(default_name, nwe_file_name_txt)
else:
msg = "你将要把文件名为{}的文件修为{},且前面不添加添加序号,确定吗?".format(default_name, nwe_file_name_txt)
dlg = wx.MessageDialog(None, msg, '提示', wx.YES_NO | wx.ICON_QUESTION)
result = dlg.ShowModal()
if result == wx.ID_YES:
txt = event_processing.Modify_file_name(Default_name=default_name, keyword=nwe_file_name_txt,name_mak=name_mak).start()
msg = ""
for i in txt:
msg += i
self.Tips_views.SetValue(msg)
else:
pass
dlg.Destroy()
event.Skip()
def copy_files(self, event):
"""
文件夹复制事件
读取文件文本框内容,整理发送给逻辑模块处理事件
:param event:
:return:
"""
self.Tips_views.Clear()
key_name=self.m_textCtrl5.GetValue()
number=int(self.m_textCtrl4.GetValue())
str_split=self.m_textCtrl6.GetValue()
txt = event_processing.Copy_folder(key_name=key_name,number=number,str_split=str_split).start()
msg = ""
for i in txt:
for item in i:
msg += item
self.Tips_views.SetValue(msg)
event.Skip()
def default_name_txtOnText(self, event):
self.Tips_views.Clear()
default_name = self.default_name_txt.GetValue().split(".")
if default_name[-1] == "txt" and "TXT":
msg = "检测到文件为\"TXT\"文档可转换为CSV表格文件\n如需转换为CSV表格文件请在新文件名后面加后缀\".CSV\""
self.Tips_views.SetValue(msg)
else:
self.Tips_views.Clear()
event.Skip()
###########################################################################
## Class Popup
###########################################################################
class Popup(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=u"警告", pos=wx.DefaultPosition, size=wx.Size(500, 300),
style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
self.SetForegroundColour(wx.Colour(255, 0, 0))
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
bSizer1 = wx.BoxSizer(wx.VERTICAL)
self.m_staticText4 = wx.StaticText(self, wx.ID_ANY,
u"请注意!\n1、本修改模式请将本工具放置在被修改文件同一目录下\n2、移除不需要修改名字的文件\n3、本工具修改文件名后不具有可回溯性",
wx.DefaultPosition, wx.DefaultSize, 0)
self.m_staticText4.Wrap(-1)
self.m_staticText4.SetForegroundColour(wx.Colour(255, 0, 0))
self.m_staticText4.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
bSizer1.Add(self.m_staticText4, 0, wx.ALL, 5)
self.m_staticText5 = wx.StaticText(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
self.m_staticText5.Wrap(-1)
bSizer1.Add(self.m_staticText5, 0, wx.ALL, 5)
self.m_staticText6 = wx.StaticText(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
self.m_staticText6.Wrap(-1)
bSizer1.Add(self.m_staticText6, 0, wx.ALL, 5)
self.m_button5 = wx.Button(self, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer1.Add(self.m_button5, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
self.SetSizer(bSizer1)
self.Layout()
self.Centre(wx.BOTH)
# Connect Events
self.m_button5.Bind(wx.EVT_BUTTON, self.close_popup)
def __del__(self):
pass
# Virtual event handlers, overide them in your derived class
def close_popup(self, event):
event.Skip()
app = wx.App()
frm = File_name_modification(None)
frm.Show()
app.MainLoop()
打包成可执行文件
命令为:
pyintsaller -F -w my_tool.py -p event_processing.py -i "你的程序图标图片.ico"
-F 打包成单个可执行文件
-w 窗口界面程序
-p 打包辅助文件
-i 添加打包后可执行文件图片
本代码书写工具只适用于局部场景,对于本博客内容有疑问或者代码有建议可以留言或邮箱交流