• 使用PyQt5自制文件查找工具,并生成EXE文件


    一、工作中,有一个关键词查找工作,查找开发版本中使用的文本,有哪些词语是非法的,一个一个去查太累了,所以想到了用代码来实现。可后来想想,能否做成简单的小工具,大家都可以使用。

    于是就着手编写工具。原来是计划用Python自带的lib库:tkinter,写的时候发现真不好操作,网上对应的说明文档也比较少。所以查找了好久,决定用PyQt5来实现。

    二、大概思路:①.使用designer.exe绘制窗体;②使用eric6生成主窗口对应的py文件;③编辑调用主窗口的程序;④使用信号(signal)和槽(slot)机制建立窗体的动作指令;⑤调试打包

    三、实现过程

    1.PyQt5的安装上篇已做介绍,打开designer.exe,新建一个ui文件。如图,放置了3个QPushButton,然后放置了QLineEdit和QTextEdit,第一个设置了默认文本(placeholderText设置),保存为openfile.ui

     

    2.在eric6中,先创建一个项目,在forms窗体,添加openfile.ui,然后编译,生成Ui_openfile.py,如下附录2中的代码

    3.创建主程序openfile.py,导入界面程序:from Ui_openfile import *,然后再导入其他需要的库。

    4.编写类class,定义其中关于界面点击的函数

     类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。方法:类中定义的函数。

    5.定义方法:findtxt,主要实现查找已有文本,是否在目标文件中。方法findtxt是一个槽函数,要与前面的信号关联起来。所以在前面的Ui_openfile.py,添加信号语句:self.button_find.clicked.connect(self.findtxt),这样信号和槽就关联起来了。

    在获取目标文件时,需要打开一个文件选择框。此时定义了另一个函数:loadtxt,实现打开文件选择控件,获取文本内容,并把目标文件的路径写在下方的文本框里。使用方法:self.loadtxt()来调用类中的另一个函数,获取目标文件内容。

    (另外:方法loadtxt也可以成为一个槽函数,要与前面的信号关联起来。可以在前面的Ui_openfile.py,添加信号语句:self.button_openfile.clicked.connect(self.loadtxt),进行信号和槽的关联)

    当查找完毕后,可以在findtxt后面添加语句: self.lineEdit.setText('结果已保存在D盘list.txt文件')。这样就可以做到通知执行结果的作用。

    6.同样的,定义方法:listappear。实现获取关键词文本内容并显示。然后在前面添加信号:self.button_keylist.clicked.connect(self.listappear),进行信号和槽函数的关联。

    7.编写完毕后,检查无问题,CMD窗口执行语句:Python openfile.py ,会自动调用Ui_openfile.py,这样一个小工具就初步告成了。

    8.编译打包。有多个py文件时,主文件放在前面即可,打包命令:C:UsersadminAppDataLocalProgramsPythonPython37Scripts>pyinstaller -F openfile.py Ui_openfile.py
    打包后生成exe文件,打开是闪退,提示错误: ImportError: unable to find Qt5Core.dll on PATH

    经过查找,参考博客 https://blog.csdn.net/zwyact/article/details/99778898 ,添加一小段代码后解决。

    四.附录程序,注意缩进时,同一文本缩进方式要保持一致(TAB间缩进和四个空格缩进,只用一种)会省去编译报错的困扰:

    报错信息:IndentationError: unexpected indent;IndentationError: expected an indented block

    解决办法,可以用文本编辑器Notepad++把当前python脚本的所有空格或Tab字符都显示出来查看,视图 -> 显示符号 -> 显示空格与制表符,这样就能看到缩进方式了。

    .主程序,很多异常都未写出来,后面逐步优化

    import sys,os
    if hasattr(sys, 'frozen'):
      os.environ['PATH'] = sys._MEIPASS + ";" + os.environ['PATH']
    from PyQt5.QtWidgets import *
    from Ui_openfile import *
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *

    file='//19.87.8.11/testtools/keywords.txt'
    class MyMainWindow(QMainWindow,Ui_mainWindow):
      def __init__(self,parent=None):
        super(MyMainWindow,self).__init__(parent)
        self.setupUi(self)
      def loadtxt(self):                #打开文本选择路径框,获取目标文本
        filename,_=QFileDialog.getOpenFileName(self,'open file','.','txt(*.txt)')                         #QFileDialog是用于打开和保存文件的标准对话框
        def readtext(filename): #读取文本内容
          fullText = []
          textcon = open(filename, 'r', encoding='utf-8')                  #使用utf-8编码打开,非此编码的文本打开有问题,可以采用忽略错误的方式
          for i in textcon:
            lincone = i.strip()
            fullText.append(lincone)
            #print(fullText)
            return ' '.join(fullText)
          textcon.close()

        if filename:
          cur_path=QDir('.')
          relative_path = cur_path.relativeFilePath(filename)
          self.folderlist.setText(relative_path)                        #显示获取文本的路径
        self.goal=readtext(filename)

      def findtxt(self):
        j=0
        text_con=open(file, 'r', encoding='utf-8')                    #关键词所在的文本
        self.loadtxt()                                                             #调用获取目标文本内容函数
        goal_con=self.goal
        for i in text_con:
          line_cone = i.strip()
          #print(line_cone)
          j = j + 1
          if line_cone in goal_con:                                         #主程序中的关键程序,写了那么多,其他都是为了这个服务,南啊
            f=open('d:/list.txt','a',encoding='utf-8')
            f.write(str(j)+line_cone+' ')
        self.lineEdit.setText('结果已保存在D盘list.txt文件')             #结果提示

      def listappear(self):           #获取关键词文本内容,展示出来。
        fullText = ''         
        textcon = open(file, 'r', encoding='utf-8')
        for i in textcon:
          lincone = i.strip()
          fullText=fullText+lincone+','
        self.keylist.setText(fullText)     #设置的文本内容是个字符串,所以不能用前面的列表形式收集。
        textcon.close()

    if __name__=="__main__":
      app=QApplication(sys.argv)  
      myWin=MyMainWindow()
      myWin.show()
      sys.exit(app.exec_())

    2.ui文件

    # -*- coding: utf-8 -*-

    # Form implementation generated from reading ui file 'D:1.soft88.Python-Ericeric6worksecondwindow.ui'
    #
    # Created by: PyQt5 UI code generator 5.13.0
    #
    # 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(662, 430)
        self.centralwidget = QtWidgets.QWidget(mainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.button_keylist = QtWidgets.QPushButton(self.centralwidget)
        self.button_keylist.setGeometry(QtCore.QRect(80, 160, 121, 41))
        self.button_keylist.setObjectName("button_keylist")
        self.keylist = QtWidgets.QTextEdit(self.centralwidget)
        self.keylist.setGeometry(QtCore.QRect(230, 160, 251, 151))
        self.keylist.setObjectName("keylist")
        self.folderlist = QtWidgets.QLineEdit(self.centralwidget)
        self.folderlist.setGeometry(QtCore.QRect(230, 100, 401, 31))
        self.folderlist.setObjectName("folderlist")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(230, 40, 241, 31))
        self.lineEdit.setObjectName("lineEdit")
        self.button_find = QtWidgets.QPushButton(self.centralwidget)
        self.button_find.setGeometry(QtCore.QRect(80, 40, 121, 31))
        self.button_find.setObjectName("button_find")
        self.button_openfile = QtWidgets.QPushButton(self.centralwidget)
        self.button_openfile.setGeometry(QtCore.QRect(80, 100, 121, 31))
        self.button_openfile.setObjectName("button_openfile")
        mainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(mainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 662, 23))
        self.menubar.setObjectName("menubar")
        mainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(mainWindow)
        self.statusbar.setObjectName("statusbar")
        mainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(mainWindow) 
        self.button_find.clicked.connect(self.findtxt)                   #信号signal
        self.button_keylist.clicked.connect(self.listappear)         #信号signal
        QtCore.QMetaObject.connectSlotsByName(mainWindow)

      def retranslateUi(self, mainWindow):
        _translate = QtCore.QCoreApplication.translate
        mainWindow.setWindowTitle(_translate("mainWindow", "关键字查询V1.0"))
        self.button_keylist.setText(_translate("mainWindow", "当前已有关键词"))
        self.lineEdit.setPlaceholderText(_translate("mainWindow", "结果保存在D盘list文本文件"))
        self.button_find.setText(_translate("mainWindow", "查找"))
        self.button_openfile.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_())

  • 相关阅读:
    Tomcat Connector的三种运行模式
    Tomcat管理页面配置
    URI、URL、URN
    利用libcurl进行post
    安装WIA组件
    wget访问SOAP接口
    haproxy+tomcat集群搭建
    Redis主从复制及状态监测
    VB6之Mandelbrot集
    leetcode Word Search
  • 原文地址:https://www.cnblogs.com/jintianniu/p/12002776.html
Copyright © 2020-2023  润新知