HyelloSonger

当编程+Linux+音乐+b站会产生怎样的火花呢?——一个初代00后的自白

自用Python版简易文本编码转换器(有Tkinter GUI)

 这个东西是今年除夕那天做的(PS:我现在是每个除夕必定要编程出一款小软件来,作为庆祝活动,哈哈),因为我有几个txt的网络小说是ansi编码的,放到utf-8的linux下打开就都是乱码了。因此写了这么一个小东西来自用,可以控制台和GUI双模式。实现原理也弱爆了:逐行读取、识别编码、然后转换。在linuxmint下运行通过,不知道别的平台能不能用。
 工具依赖chardet库,不过你可以把代码改成强制源文件编码来去掉对它的依赖。
 文件不大,干脆直接贴代码得了:

#!/usr/bin/env python2
 # -*- coding: utf-8 -*-
 #
 #  encoding_translate.py
 # 
 #  Copyright 2016 Hyello Song
 # 
 
from sys import argv
from chardet import detect
from Tkinter import *
from tkMessageBox import *
 
DEFAULT_ENCODING='gb2312' #伪常量
GUI_TIP='''文本文件编码转换器 By:Hyello
 访问我的网站:www.hyello.org
 本工具有命令行与GUI两种模式
 注:./代表本工具所在的目录
 命令行加上-help参数获取更详细信息'''
CONSOLE_TIP='''Usage:./encoding_translate.py 源文件 目标文件 是否自动删除空行(可选,1为删除,0为不删除) 是否强制默认编码(要求同上个参数)
 
 一个可以转换文本文件编码的小工具,可用于解决Windows/Unix的跨平台编码问题!
 用Python编写,可以跨平台!
 本工具有命令行与GUI两种模式。注:./代表本工具所在的目录。
 转换过程中控制台会输出实时信息,可以用>管道符号存储日志,方法为:
 ./encoding_translate.py ...(各种参数)...>log.txt
 注:强制默认编码的选项用于chardet识别不正常的时候。
By Hyello 个人网站:www.hyello.org E-mail:hyello@163.com
 
 **********本工具依赖以下库,请使用pip安装**********
chardet(用于自动识别每行的编码。如果实在没法安装,请自行修改代码)
 '''
 
if __name__ != '__main__':
     exit()
 
 # 呵呵……有这么一些属性:text是文本,background是背景色,foreground是前景色(颜色可以用英语单词或者#rrggbb表示),font是字体,格式为'字体名称 文字尺寸'
 # underline表示看不懂文档。。。
def butDo_click():
     code_turn(varS.get(), varD.get(), varIs.get(), varForce.get())
     showinfo('转换完毕', '转换完毕,请打开目标文件确认转换情况,具体细节请参考控制台输出信息')
     #tkMessageBox可以打开各种各样的对话框~具体请pydoc一下
     #lblTest1['text']='aha!文字被改变了'
     #上面一行执行成功,说明控件可以像字典一样调用,屌不屌?!字典项就是控件属性
     #这个调用方式在自定义类里面的实现。。。还需要研究一下
    
def code_turn(source, destination, delEmptyLine=False, forceDefault=False):
     print '**********开始以系统默认编码转换%s到%s**********'%(source, destination)
     fileS = open(source, 'r')
     fileD = open(destination, 'w')
     flag=6666 #这里只要不是0都行
     n=0
     while flag!=fileS.tell():
         n+=1
         flag = fileS.tell()
         line=fileS.readline()
         print '转码第%d行,位置于%d字节......'%(n, fileS.tell()),
         if (not delEmptyLine) or (line.strip()!=''):
             encoding=detect(line)['encoding']
             print '文件编码为%r,可信度为%f'%(encoding, detect(line)['confidence']),
             try:
                 if not forceDefault:
                     fileD.write(line.decode((encoding, DEFAULT_ENCODING)[int(encoding==None)], 'replace'))
                 else:
                     __forcetrans__(line, fileD)
             except:
                 __forcetrans__(line, fileD) #当普通转码出错时,启用强制转码
             print '完成写入'
         else:
             print '空行已跳过'
     print '**********转码完成**********'
def __forcetrans__(ln, fl):
         fl.write(ln.decode(DEFAULT_ENCODING, 'replace'))
         print '因特殊情况强制使用%r编码,'�FAULT_ENCODING,
 
 #如果从控制台载入的话……
if len(argv)>1:
     print '**********命令行模式**********'
     if argv[1]=='-help':
         print CONSOLE_TIP
     elif len(argv)<3:
         print '参数不足!'
     elif len(argv)==3:
         code_turn(argv[1], argv[2])
     elif len(argv)==4:
         code_turn(argv[1], argv[2], argv[3])
     else:
         code_turn(argv[1], argv[2], argv[3], argv[4])
     exit()
 
print '**********图形界面模式**********'
 
mainForm=Tk()
mainForm.title('文本文件编码转换器')
 #控件加载代码
varS=StringVar() #StringVar可是Tkinter库提供的奇葩东西,set方法设置值,get方法获取值
varD=StringVar()
entSource=Entry(mainForm, font=' 1', textvariable=varS)
entDestination=Entry(mainForm, font=' 1', textvariable=varD)
varS.set(r'./')
varD.set(r'./')
 
butDo=Button(mainForm, font=' 1', text='开始转换', command=butDo_click, bd=3)
 
varIs=IntVar() #和StringVar那货类似
varForce=IntVar()
cbuDel=Checkbutton(mainForm, font=' 1', text='是否自动删除空行', variable=varIs)
cbuForce=Checkbutton(mainForm, font=' 1', text='是否强制使用GB2312编码', variable=varForce)
 
lblAbout=Label(mainForm, font=' 1', text=GUI_TIP)
lblSource=Label(mainForm, font=' 1', text='源文件名:')
lblDestination=Label(mainForm, font=' 1', text='目标文件名:')
 
 #布局代码
lblSource.grid(row=0, column=0, sticky=W)
entSource.grid(row=0, column=1, sticky=E)
lblDestination.grid(row=1, column=0, sticky=W)
entDestination.grid(row=1, column=1, sticky=E)
cbuDel.grid(row=2, column=1)
cbuForce.grid(row=3, column=1)
lblAbout.grid(row=4, column=1)
butDo.grid(row=4, column=0)
 
mainForm.mainloop()

评论

© HyelloSonger | Powered by LOFTER