python 文本处理与tkinter入门
工作需要,得开发一些带GUI的小工具
在此记录下踩的坑
源码
使用from ... import ...
是为了尽量减小打包后文件的大小
文中和Canvas, PhotoImage, ico, bitmap
有关的语句也是为了减小打包后exe尺寸而注释掉的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# import tkinter as tk # from tkinter import Canvas, Label, StringVar, Entry, Button, Tk, PhotoImage, messagebox from tkinter import Label, StringVar, Entry, Button, Tk, messagebox # 窗口居中显示函数 def center_window(root, width, height): screenwidth = root.winfo_screenwidth() screenheight = root.winfo_screenheight() size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) # print(size) root.geometry(size) root.update() # print(root.winfo_x()) # 创建窗口 window = Tk() window.title('文本自动划分软件 2.0') # window.geometry('500x200+1000+500') # 宽500, 高200,距左边1000,距上边500 center_window(window, 280, 200) # ico_file = r'./TaiJi.ico'# 载入图标ico文件 # window.iconbitmap(bitmap=ico_file) # 设置窗口图标 ###创建logo ##canvas = Canvas(window, height=150, width=150) # 创建画布 ##img_file = PhotoImage(file=r'./Tai_Ji_Animation.gif') # 读取图片文件,只支持gif ##img = canvas.create_image(0,0, anchor='nw', image = img_file) # 放置图片于画布上, anchor后是按照方位表示的锚点位置 ##canvas.pack(side='top') # 放置画布 # 创建标签 Label(window, text='文件名:').place(x=50, y= 50) Label(window, text='(.txt)').place(x=200, y= 50) note = '''说明:待转换文件和该程序 需在同一文件中''' Label(window, text=note).place(x=50, y= 80) # 变量赋值 var_file_name = StringVar() var_file_name.set('1000') # 创建文件名输入示例 entry_file_name = Entry(window, textvariable=var_file_name, width=10) entry_file_name.place(x=100, y=50) # 文本转换代码(需要放在按钮前,以供按钮调用) def text_convert(): try: name = entry_file_name.get() # 读取entry框中的文本内容 # open file readlines and save each line as a entity in data (type:list) with open(r'./'+name+'.txt', 'r') as f: data = f.readlines() # delete the row changing sign at the end of each row data = [i.strip('\n\t') for i in data] # a new list to hold concated data smpl = [] mod = len(data)//30 # the largest integer for i in range(mod): smpl.append('##'.join(data[i*30:i*30+29])) smpl.append('##'.join(data[mod*30:len(data)])) # put rest info to the last line smpl = ['======【第'+str(smpl.index(line)+1)+'行】======\n'+line+'\r' for line in smpl] # '\r\n' both stand for a new line with open(r'./'+name+'_30.txt','w') as f: f.writelines(smpl) messagebox.showinfo(title='Done', message='转换完成,共转换数据'+str(len(data))+'条\n结果文件名为'+name+'_30.txt') except FileNotFoundError: # 未找到文件时报错 messagebox.showerror(title='Error', message='该文件夹中未找到'+name+'.txt\n') # 运行按钮 btn_run = Button(window, text='开始转换', command=text_convert)#定义一个`button`按钮,名为`开始转换`,触发命令为`text_convert` btn_run.place(x=110, y=120) # 如果不加这条,打包后的exe窗口会闪退 window.mainloop() print('sucessfully run') |
参考网站:
感谢知识分享!
二次更新
增加csv对比模块
本来是用xlsx,但是pandas和openpyxl的打包一直无法成功,为此还自己写了CMD脚本
于是想到用csv,恰好python可以不借助其他包读写csv,因此快速试试。
亮点:
- 多次使用一行代码实现遍历处理,例如lambda函数的使用
- 利用index返回索引,读取csv中对应位置的信息
- try, except的丰富
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
top_y_2 = 140 Label(window, text='数据库:').place(x=50, y= top_y_2) Label(window, text='(.txt)').place(x=200, y= top_y_2) var_ref_name = StringVar() var_ref_name.set('200') entry_ref_name = Entry(window, textvariable=var_ref_name, width=10) entry_ref_name.place(x=100, y=top_y_2) Label(window, text='待对比:').place(x=50, y= top_y_2+30) Label(window, text='(.csv)').place(x=200, y= top_y_2+30) var_ln_name = StringVar() var_ln_name.set('测试') entry_ln_name = Entry(window, textvariable=var_ln_name, width=10) entry_ln_name.place(x=100, y=top_y_2+30) def examine(): ref_name = entry_ref_name.get() ln_name = entry_ln_name.get() try: with open('./'+str(ref_name)+'.txt','r',encoding='utf-8') as f: refs = [ref.strip('\n') for ref in f.readlines()] # 逐行读取并消除首尾字符 with open('./'+str(ln_name)+'.csv','r',encoding='utf-8') as f: lines = [line.strip('\n') for line in f.readlines()] # 读取各行逗号索引值 # 截取微信号列,+1以跳过开头逗号 idxes = [[i for i,s in enumerate(line) if s==','] for line in lines] numbers = [line[idx[0]+1:idx[1]] for idx, line in zip(idxes,lines)] judge = lambda x:x if x in refs else '' # 单独定义比较函数 sames = [judge(number) for number in numbers] sames[0] = '重复项' # 补个header outs = [line+same+',\n' for line,same in zip(lines, sames)] with open('./'+str(ln_name)+'_1'+'.csv','w',encoding='utf-8') as f: f.writelines(outs) messagebox.showinfo(title='Done', message= '参考给出的'+str(len(refs))+'条数据\n' +'本次筛选的'+str(len(lines)-lines.count(''))+'条的数据中\n' +'包含重复数据'+str(len(sames)-sames.count(''))+'条\n' +'处理结果保存至“'+str(ln_name)+'_1'+'.csv”中') except FileNotFoundError: messagebox.showerror(title='Error', message='该文件夹中未找到“'+ref_name+'.txt”\n'+'或“'+ln_name+'.csv”') except Exception as e: messagebox.showerror(title='Error', message='错误类型:“'+str(e)+'”\n错误日志已自动保存至该文件夹“error_log.txt”中\n请联系开发者并发送该报告') with open('./error_log'+'.txt','w',encoding='utf-8') as f: f.writelines(str(e)) # 运行按钮 btn_run = Button(window, text='开始筛选', command=examine) btn_run.place(x=110, y=top_y_2+60) |
写的两个bat批处理文件:
- pyinstaller自动安装
123456call activate text_3.6D:cd XYX\TMP\XiongXi\0731_Datapyinstaller -F -w TC-4.0.1.py -i hd.icopauseexit - 运行并记录日志
12345D:cd XYX\TMP\XiongXi\0731_Data\distTC_2.exe>log.txt 2>&1pauseexit - 自动创建环境并安装所需库
这里尝试3.6和3.8是因为看到github讨论中说pyinstaller对3.7的支持兼容不好
12conda create python=3.6 -n text_3.6 pandas pyinstaller -yconda create python=3.8 -n text_3.8 pandas pyinstaller -y
其他
pyinstaller打包图标不变,可能由于explore.exe有缓存,或是由于ico对应不同尺寸的图标
如果无需担心两个集合内部的顺序,可以用【set】,考虑顺序,还是建议上述方法。