对于一些常用的 Python 脚本,如果我们想把它打包给其他人使用,不用安装Python环境而直接使用。这时候就涉及到界面编程,让普通用户也能用上是多么酷的事情。本次利用Qt Desiger工具可视化设计做了一个word转pf的小工具,手把手教你完成一个具有完整项目结构的小项目,接下来你也可以根据需要给自己的小脚本添加拓展界面啦!
还增加了一个简单的计价功能,当然,在此基础上可以拓展字数统计、加水印等功能,也可以把Microsoft Word中PDF工具功能一一实现。
1、开发工具配置
1、安装独立的项目环境,全局环境存在版本冲突,不方便项目迁移;且打包可减少不必要的模块,需要创建虚拟环境隔离。
2、pipenv工具可以创建虚拟环境并且将需要的插件模块版本记录下来
3、安装pipenv工具:pip install pipenv;本次项目需要准备安装的包有:PyQt5、pyqt5-tools、pywin32、PyPDF2。
2、创建项目目录
代码语言:javascript复制1)、创建目录
mkdir myProjectfile (linux、window通用,当然也可以手动建一个文件夹命名)
2)进入目录
cd myProjectfile (也可以直接打开建立的文件夹路径cmd命令进入)
3)配置虚拟环境路径
linux: export PIPENV_VENV_IN_PROJECT=1
window: set PIPENV_VENV_IN_PROJECT=1 (注意项目不能在C盘,如果此处没有设置,默认虚拟环境路径在C盘下)
4)创建虚拟环境
pipenv install
5)激化环境
pipenv shell
6)安装需要的包
pipenv install PyQt5/pyqt5-tools/pywin32/PyPDF2
3、项目文件夹结构
项目组织设计采用UI界面和逻辑代码分离的结构。
一、窗体可视化设计
本次主要设计实现一个子窗体word转pdf的代码实现。先设计好可视化操作界面,直接在QT designer中进行可视化界面设计主窗体文件和Word转PDF窗体文件,保存在ui界面文件夹中,然后利用pyuic5转化为可视化界面的py文件,将其拷贝上一级目录,如有修改记得覆盖更新。具体uic.bat脚本内容如下:
代码语言:javascript复制pyuic5 -o ui_mainWindow.py mainWindow.ui
pyuic5 -o ui_transformWindow.py transformWindow.ui
二、功能模块的编写
本次在项目子目录tools中自定义封装三个模块:1、common模块,完成文件夹路径读取相关操作,同时可对文件排序规则定义;2、wordtopdf模块,主要将word批量转换为pdf,并移动到指定目标路径;3、mergepdf模块,主要实现多个pdf文件合并,同时统计页码
common模块部分代码
代码语言:javascript复制def all_path(dirname):
result = []
for maindir, subdir, file_name_list in os.walk(dirname):
for filename in file_name_list:
apath = os.path.join(maindir, filename)
result.append(apath)
return result
def GetExtNamesList(fileslist,ext):
filenames=[]
for file in fileslist:
fileinfo=os.path.splitext(file)
if fileinfo[1]==ext:
filenames.append(file)
return filenames
代码语言:javascript复制wordtopdf模块代码
from win32com.client import Dispatch # 导入pywin32模块的client包下的函数
import os,shutil
import tools.common as common
def doc2pdf(input_file):
word = Dispatch('Word.Application')
doc = word.Documents.Open(input_file)
if input_file.endswith(".docx"):
doc.SaveAs(input_file.replace(".docx", ".pdf"), FileFormat=17)
doc.Close()
word.Quit()
else:
doc.SaveAs(input_file.replace(".doc", ".pdf"), FileFormat=17)
doc.Close()
word.Quit()
return
def pdfmove(path,targetpath):
filelist=common.GetExtNamesList(common.all_path(path),'.pdf')
for file in filelist:
targetname=file.replace('\','/').replace(targetpath,path)
if not os.path.exists(os.path.dirname(targetpath)):
os.makedirs(os.path.dirname(targetpath))
if os.path.exists(targetname):
shutil.move(file,targetpath)
return
def wordtopdf(filelist,targetpath):
valueList = []
try:
for fullfilename in filelist:
temp = fullfilename.split('\')
path = temp[0]
print("路径",path)
filename = temp[1]
os.chdir(path)
doc = os.path.abspath(filename)
os.chdir(targetpath)
pdf_name = doc.split(".")[0] ".pdf"
valueList.append("{0}".format(pdf_name))
input_file = fullfilename.replace('\', '/')
doc2pdf(input_file)
pdfmove(path, targetpath)
return valueList
except TypeError as e:
print('出错了!')
print(e)
return -1
mergepdf模块
代码语言:javascript复制import os, sys
from PyPDF2 import PdfFileReader, PdfFileMerger,PdfFileWriter
import tools.common as common
def MergePDF(targetpath, file_name="merge.pdf"):
# 实例化写入对象
output = PdfFileWriter()
outputPages = 0
value_List = []
# 调用上一个函数获取全部文件的绝对路径
file_list=common.GetExtNamesList(common.all_path(targetpath), '.pdf')
if len(file_list) == 0:
print("当前目录及子目录下不存在pdf文件")
sys.exit()
for pdf_file in file_list:
print("文件:%s" % pdf_file.split('\')[-1], end=' ')
# 读取PDF文件
input = PdfFileReader(open(pdf_file, "rb"))
# 获得源PDF文件中页面总数
pageCount = input.getNumPages()
value_List.append([pdf_file, str(pageCount)])
outputPages = pageCount
print("页数:%d" % pageCount)
# 分别将page添加到输出output中
for iPage in range(pageCount):
output.addPage(input.getPage(iPage))
print("n合并后的总页数:%d" % outputPages)
# 写入到目标PDF文件
print("PDF文件正在合并,请稍等......")
with open(os.path.join(targetpath,"merge.pdf"), "wb") as outputfile:
output.write(outputfile)
print("PDF文件合并完成")
return outputPages,value_List
代码语言:javascript复制
三、进行槽函数和操作界面关联
点击界面触发信号,连接槽函数并调用我们编写好的功能函数(可参考往期转载的相关推文,可以去这几个优质公众号学习哦,
代码语言:javascript复制