在配置好python3+PyQt5 + eric6 的环境后,QT Designer 软件下载安装,就可以开始尝试python GUI 开发,初步熟悉阶段主要参照网上的博客《用eric6与PyQt5实现python的极速GUI编程》,此外对PyQt5的学习可以参考《PyQt5学习笔记》。
在了解和熟悉整个流程之后就开始尝试自己给之前写的最大逆向匹配分词程序编写一个易操作的可视化界面,实现界面如下图所示:
主要步骤如下:
1、在eric6中新建项目
2、进入 QT Designer 编辑图像界面并保存
3、回到eric 6 将刚才的界面文件编译
4、新建一个python文件,给界面添加自己的程序逻辑
5、PyInstaller 打包成exe文件(此步暂未实现,下次再详细说明)
步骤1:eric6 中新建项目
打开eric6,点击菜单栏的“项目”选项---->"新建项目",弹出“项目属性”对话框,在“项目名称”一栏输入新建项目的名字,如"test",在”项目文件夹“一栏可以通过旁边的按钮选择新建的项目所要存储的位置,点击”OK“,弹出”是否将已有文件添加到项目中?“对话框,默认点击”yes",接着弹出”文件关联“对话框,同样默认点击”OK“,项目新建完成。如下图所示,新建项目初始自动生成了__init__.py文件,点击左上角的绿色窗体按钮,新建窗体(即我们所需的可视化界面)。
新建窗体:右击按钮下方的空白区域,会弹出包含新建窗体的对话框,单击“新建窗体”,弹出“窗体类型”对话框,可以根据实际需求选择,在这里我选择“主窗体”类型,点击“ok”,窗体新建完成。
步骤2、进入 QT Designer 编辑图像界面并保存
参考《PyQt5学习笔记》,给界面添加 lable,pushbutton,Line Edit 类型的控件,并且更改对应的objectName.利用PyQT特有的“信号-槽”功能直接给“退出”按钮添加关闭窗口的功能,在配置连接的对话框里,右侧栏的函数要点击了左侧栏中的任意一个函数才能够选择,左下角的单选框也应该勾选起。
步骤3、回到eric 6 将刚才的界面文件编译
右击main.ui窗体,弹出包含“编译窗体”选项的对话框,点击编译窗体,自动生成新的Ui_main.py 文件。
自动生成的Ui_main.py 中的源码如下所示:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'F:\pythonStudyforGroup\task9\main.ui'
#
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(562, 600)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.gridLayoutWidget = QtWidgets.QWidget(self.centralWidget)
self.gridLayoutWidget.setGeometry(QtCore.QRect(30, 90, 211, 331))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.add_dic_lable = QtWidgets.QLabel(self.gridLayoutWidget)
self.add_dic_lable.setAlignment(QtCore.Qt.AlignCenter)
self.add_dic_lable.setObjectName("add_dic_lable")
self.verticalLayout.addWidget(self.add_dic_lable)
self.dic_url = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.dic_url.setObjectName("dic_url")
self.verticalLayout.addWidget(self.dic_url)
self.add_dic = QtWidgets.QPushButton(self.gridLayoutWidget)
self.add_dic.setObjectName("add_dic")
self.verticalLayout.addWidget(self.add_dic)
self.add_rawfile_lable = QtWidgets.QLabel(self.gridLayoutWidget)
self.add_rawfile_lable.setAlignment(QtCore.Qt.AlignCenter)
self.add_rawfile_lable.setObjectName("add_rawfile_lable")
self.verticalLayout.addWidget(self.add_rawfile_lable)
self.rawfile_url = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.rawfile_url.setObjectName("rawfile_url")
self.verticalLayout.addWidget(self.rawfile_url)
self.add_rawfile = QtWidgets.QPushButton(self.gridLayoutWidget)
self.add_rawfile.setObjectName("add_rawfile")
self.verticalLayout.addWidget(self.add_rawfile)
self.words_cut_lable = QtWidgets.QLabel(self.gridLayoutWidget)
self.words_cut_lable.setAlignment(QtCore.Qt.AlignCenter)
self.words_cut_lable.setObjectName("words_cut_lable")
self.verticalLayout.addWidget(self.words_cut_lable)
self.words_cut = QtWidgets.QPushButton(self.gridLayoutWidget)
self.words_cut.setObjectName("words_cut")
self.verticalLayout.addWidget(self.words_cut)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
self.gridLayoutWidget_2 = QtWidgets.QWidget(self.centralWidget)
self.gridLayoutWidget_2.setGeometry(QtCore.QRect(270, 88, 258, 331))
self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
self.gridLayout_2.setObjectName("gridLayout_2")
self.words_cut_result = QtWidgets.QTextEdit(self.gridLayoutWidget_2)
self.words_cut_result.setObjectName("words_cut_result")
self.gridLayout_2.addWidget(self.words_cut_result, 2, 0, 1, 1)
self.show_result = QtWidgets.QPushButton(self.gridLayoutWidget_2)
self.show_result.setObjectName("show_result")
self.gridLayout_2.addWidget(self.show_result, 1, 0, 1, 1)
self.words_cut_feedback = QtWidgets.QLineEdit(self.gridLayoutWidget_2)
self.words_cut_feedback.setObjectName("words_cut_feedback")
self.gridLayout_2.addWidget(self.words_cut_feedback, 0, 0, 1, 1)
self.title = QtWidgets.QLabel(self.centralWidget)
self.title.setGeometry(QtCore.QRect(170, 30, 161, 31))
self.title.setAlignment(QtCore.Qt.AlignCenter)
self.title.setObjectName("title")
self.exit = QtWidgets.QPushButton(self.centralWidget)
self.exit.setGeometry(QtCore.QRect(220, 470, 75, 23))
self.exit.setObjectName("exit")
self.retranslateUi(MainWindow)
self.exit.clicked.connect(MainWindow.close)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.add_dic_lable.setText(_translate("MainWindow", "添加分词字典"))
self.add_dic.setText(_translate("MainWindow", "添加字典"))
self.add_rawfile_lable.setText(_translate("MainWindow", "添加待分词文本"))
self.add_rawfile.setText(_translate("MainWindow", "添加文本"))
self.words_cut_lable.setText(_translate("MainWindow", "最大逆向匹配分词"))
self.words_cut.setText(_translate("MainWindow", "开始分词"))
self.show_result.setText(_translate("MainWindow", "查看分词结果"))
self.title.setText(_translate("MainWindow", "最大逆向匹配分词"))
self.exit.setText(_translate("MainWindow", "退出"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
给界面添加自己的程序逻辑也可以直接在自动生成的Ui_main.py里添加,在这里新建一个python程序是希望可以界面设计和程序逻辑能够分离。
这里对界面添加逻辑主要包括以下几部分:
(1)添加分词字典按钮:能够打开分词字典文件,获取分词字典的URL,显示在其上的文本框中
(2)添加待分词文本:能够打开待分词文本,获取待分词文本的URL,显示在其上的文本框中
(3)开始分词:获取分词字典的URL,待分词文本的URL,进行分词,将分词结果存储的URL显示在右上角的文本框中。
(4)查看分词结果:获取分词结果的URL,读取分词结果文本中的内容,将其显示在右下角的文本框中。
主要涉及的函数有:
(1)将按钮和其触发的函数相连
self.add_dic.clicked.connect(self.dictory)
self.add_rawfile.clicked.connect(self.rawfile)
self.words_cut.clicked.connect(self.wordscut)
self.show_result.clicked.connect(self.resultshow)
(2)选取文件
filename1, filetype =QFileDialog.getOpenFileName(self, "选取文件", " ", "All Files(*);;Text Files(*.txt)")
(3)获取文本框的值
rawfile_path=self.rawfile_url.text()
(4)赋予文本框值
self.rawfile_url.setText(filename2)
新建的task.py 详细代码如下所示:
from PyQt5 import QtWidgets
from Ui_main import Ui_MainWindow
from PyQt5.QtWidgets import QFileDialog
import codecs
import os
import xlrd
import shutil
class mywindow(QtWidgets.QWidget, Ui_MainWindow):
def __init__ (self):
super(mywindow, self).__init__()
self.setupUi(self)
self.add_dic.clicked.connect(self.dictory)
self.add_rawfile.clicked.connect(self.rawfile)
self.words_cut.clicked.connect(self.wordscut)
self.show_result.clicked.connect(self.resultshow)
#添加字典
def dictory(self):
'''
#选取文件夹
directory1 = QFileDialog.getExistingDirectory(self, "选取文件夹", "C:/")
print(directory1)
'''
#选取文件
filename1, filetype =QFileDialog.getOpenFileName(self, "选取文件", " ", "All Files(*);;Text Files(*.txt)")
print(filename1, filetype)
self.dic_url.setText(filename1)
#添加待分词文本
def rawfile(self):
#选取待分词文本
filename2, filetype=QFileDialog.getOpenFileName(self, "选取文件", " ", "All Files(*);;Text Files(*,txt)")
self.rawfile_url.setText(filename2)
#最大逆向匹配法分词
def wordscut(self):
# 创建分词结果存储文件夹
save_folder_path = r"分词结果"
if os.path.exists(save_folder_path):
shutil.rmtree(save_folder_path)
os.makedirs(save_folder_path)
else:
os.makedirs(save_folder_path)
#获取分词文本
rawfile_path=self.rawfile_url.text()
with codecs.open(rawfile_path,"r","utf8") as f:
raw_file=f.read()
#获取分词词典
dic_path = self.dic_url.text()
excel = xlrd.open_workbook(dic_path)
sheet = excel.sheets()[0]
# 读取第二列的数据
data_list = list(sheet.col_values(1))[1:]
word_dic=data_list
#分句
#设置分句的标志
cut_list=".?! 。?!"
#检查某字符是否是分句标志,如果是返回true,否则返回false
def Fundtoken(cut_list,char):
if char in cut_list:
return True
else:
return False
def cut(cut_list,lines):
l=[]
line=[]
for i in lines:
if Fundtoken(cut_list,i):
line.append(i)
l.append("".join(line))
line=[]
else:
line.append(i)
return l
sentences = cut(list(cut_list),raw_file)
sentences_list=[]
for sentence in sentences:
if sentence.strip() != "":
li = sentence.strip().split()
sentences_list.append(li[0])
raw_sentences=sentences_list
#分词
word_cut=[]
#最大词长,分词词典中的最大词长
max_length=max(len(word) for word in word_dic)
for sentence in raw_sentences:
sentence=sentence.strip()
#单句中的字数words_length,因为range函数,所以不需要减一
words_length = len(sentence)
cut_word_list=[]
#判断句子是否切分完毕
while words_length > 0:
max_cut_length = min(words_length, max_length)
for i in range(max_cut_length, 0, -1):
new_word = sentence[words_length - i: words_length]
if new_word in word_dic:
cut_word_list.append(new_word)
words_length = words_length - i
break
elif i == 1:
cut_word_list.append(new_word)
words_length = words_length - 1
cut_word_list.reverse()
words="/".join(cut_word_list)
word_cut.append(words.lstrip("/"))
content_cut=word_cut
#输出文本
outfile_path = r"result"
out_path = r"%s\%s_cut.txt" % (save_folder_path, outfile_path)
with codecs.open(out_path,"a","utf8") as f:
for sentence in content_cut:
f.write(sentence+"\r\n")
self.words_cut_feedback.setText(out_path+"**分词成功!")
print("well done!")
#显示分词结果
def resultshow(self):
feedback=self.words_cut_feedback.text()
result_path=feedback.split("*")[0]
with codecs.open(result_path, "r", "utf8") as f:
stringfile=f.read()
self.words_cut_result.setText(stringfile)
if __name__=="__main__":
import sys
app=QtWidgets.QApplication(sys.argv)
myshow=mywindow()
myshow.show()
sys.exit(app.exec_())
至此,暂时初步实现了python3 GUI的开发,还差一步把它打包成EXE文件,下次再倒腾一下,fighting~