zoukankan      html  css  js  c++  java
  • python 打包exe程序

    安装python环境

    https://www.python.org/downloads/windows/

    安装pyinstaller

    pip install pyinstaller
    

    准备python源码

    
    from tkinter import Tk
    from tkinter import Button
    from tkinter import INSERT
    from tkinter import END
    from tkinter import WORD
    from tkinter import BOTH
    from tkinter.scrolledtext import ScrolledText
    import tkinter.filedialog
    import tkinter.messagebox
    import xml.dom.minidom
    import os
    import re
    import string
    
    g_timeout = 4   # 4秒超时
    
    
    # 通讯参数
    g_param = {
        "ProtocolType": "0x00",
        "PHYPort": "0x00",
        "FunctionAddress": "0x00",
        "ECUAddress": "0x00",
        "TesterAddress": "0xF1",
        "Baudrate": "500",
        "TIdle": "300",
        "TWup": "50",
        "P1Min": "0",
        "P1Max": "20",
        "P2Min": "25",
        "P2Max": "50",
        "P3Min": "55",
        "P3Max": "5000",
        "P4Min": "5",
        "P4Max": "20",
        "CanPhysReqId": "0x710",
        "CanFuncReqId": "0x7DF",
        "Equipment_Serv_Id": "0x00",
        "Ecu_Time_T1": "0x00",
        "Ecu_Time_T2": "0x00",
        "Ecu_Time_T3": "0x00",
        "Ecu_Time_T4": "0x00",
        "Tester_Time_T1": "0x00",
        "Tester_Time_T2": "0x00",
        "Tester_Time_T3": "0x00",
        "Tester_Time_T4": "0x00",
    }
    
    # 日志中解析的报文结构
    class Packet:
        id = ""
        thread = ""
        process = ""
        time = 0
        content = []
        content_string = ""
        valid = True
    
        def __init__(self, id, thread, process ,content, content_string, time):
            self.id = id
            self.thread = thread
            self.process = process
            self.content = content
            self.content_string = content_string
            self.time = time
    
    # 对应xml
    class Service:
        req = ""
        res = ""
    
        def __init__(self, req, res):
            self.req = req
            self.res = res
    
    # 对应xml
    class Section:
        name = ""
        sid = ""
        rid = ""
        services = []
    
        def __init__(self, sid, rid):
            self.name = sid + "_" + rid
            self.sid = sid
            self.rid = rid
            self.services = []
    
    class Main():
        packets = []
        xmlFile = []
    
        def __init__(self):
            self.win = Tk()
            self.initWin()
            self.log = ScrolledText(self.win, wrap=WORD, height=40)
            self.log.pack(side="bottom", fill=BOTH)
            self.initBtn()
            self.win.mainloop()
    
        def initWin(self):
            self.win.title("Log")
            self.win.geometry("600x600")
            self.win.resizable(width=False,height=False)
    
        def initBtn(self):
            Button(self.win, text="选择日志文件..", command=self.GetResource).place(x=10, y=10)
            Button(self.win, text="导出结果文件", command=self.GenerateXML).place(x=110, y=10)
    
        # 打开文件 获取所有报文内容
        def GetResource(self):
            default_dir = r"C:\"
            self.filePath = tkinter.filedialog.askopenfilename(title=u'选择文件', initialdir=(os.path.expanduser(default_dir)))
    
            try:
                f= open(self.filePath,  'r', encoding='UTF-8', errors='ignore')
            except IOError as e:
                Tk.messagebox.showerror(title = '错误', message='打开文件失败')
                return
            
            patternPacket = re.compile('^[A-Z]+ ([0-9]*) (?P<time>[0-9]*).([0-9]*) (?P<thread_num>[a-zA-Z0-9]*)::(?P<process_num>[a-zA-Z0-9]*) [([a-zA-Z]*)] OS[<|>] (?P<id>[a-zA-Z0-9]*) (?P<content>[^"]*)')
            patternOdbParam = re.compile('^[A-Z]+ ([0-9]*) ([0-9]*).([0-9]*) ([a-zA-Z0-9]*)::([a-zA-Z0-9]*) [([a-zA-Z]*)] ObdOpen(port=([0-9]*),proto=([0-9]*),rate=([a-zA-Z0-9]*),fadr=([a-zA-Z0-9]*),eadr=([a-zA-Z0-9]*),tadr=([a-zA-Z0-9]*),sid=0x(?P<sid>[a-zA-Z0-9]*),rid=0x(?P<rid>[a-zA-Z0-9]*))')
            
            self.log.delete(0.0, END)
            lines = f.readlines()
            for line in lines:
                if (-1 != line.find("[vcicore] ObdOpen(port=")):
                    regMatch = patternOdbParam.match(line)
                    if None != regMatch:
                        linebits = regMatch.groupdict()
                        sid = linebits['sid']
                        rid = linebits['rid']
                        # 去重
                        if (self.RemoveDuplication(sid, rid)):
                            section = Section(sid, rid)
                            self.xmlFile.append(section)
                if (-1 != line.find("[vcicore] OS")):
                    regMatch = patternPacket.match(line)
                    if None != regMatch:
                        linebits = regMatch.groupdict()
                        content_string = content = linebits['content'].replace("
    ","")
                        content = content_string.split(' ')
                        # 36刷写报文只取部分
                        if (len(content) > 20
                        and content[0] == "36"):
                            content = content[:3]
                            content_string = content_string[:8]
                        packet = Packet(linebits['id'], linebits['thread_num'], linebits['process_num'], content, content_string, int(linebits['time']))    
                        self.log.insert(INSERT, linebits['id']+ " " +content_string +'
    ')
                        self.packets.append(packet)
            f.close()
    
        # 生成xml文件
        def GenerateXML(self):
            cnt = 0
            for element in self.xmlFile:
                self.Organize(element)
                if (len(element.services) != 0):
                    self.CreateFile(element)
                    cnt = cnt + 1
            tkinter.messagebox.showwarning(title = '完成',message='共生成'+str(cnt)+'个文件')
            self.filePath = ""
    
        # 判断是否重复
        def RemoveDuplication(self, sid, rid):
            for e in self.xmlFile:
                if (sid == e.sid and rid == e.rid):
                    return False
            return True
    
        # 验证是否是对应的收发报文
        def Calibrate(self, req, res):
            if (req.process == res.process and req.thread == res.thread):
                if (len(req.content) > 0 and len(res.content) > 0):
                        if (res.content[0] == "7F"): #7F的特殊情况
                            return True
                        if (64 == int(res.content[0], 16) - int(req.content[0], 16)):
                            return True
            return False
    
        # 整理报文对应的文件
        def Organize(self, section):
            cnt_record = 0
    
            while (True):
                if (0 == len(self.packets)):
                    break   # 报文列表为空,退出
    
                #找到一个发送id
                cnt_sid = -1
                index = cnt_record
                while (index < len(self.packets)):
                    if (self.packets[index].valid
                        and section.sid == self.packets[index].id):
                        cnt_sid = index
                        #找到的发送报文设置无效标记
                        self.packets[index].valid = False
                        break
                    index += 1
                    cnt_record = index
                
                #sid未找到,列表中没有需要的报文,退出
                if (-1 == cnt_sid):
                    break
    
                #找到报文发送id对应的接收id
                cnt_rid = -1
                index = cnt_sid + 1
                sid_head = self.packets[cnt_sid].content[0] #发送报文的头部
                max_time = self.packets[cnt_sid].time + g_timeout #最大寻找时间
                while (index < len(self.packets)):
                    if (self.packets[index].valid
                        and section.rid == self.packets[index].id
                        and self.packets[index].time < max_time):
                        #判断是延时帧(7F xx 78)
                        if (len(self.packets) > 2
                            and self.packets[index].content[0] == "7F"
                            and self.packets[index].content[1] == sid_head
                            and self.packets[index].content[2] == "78"):
                            max_time = self.packets[index].time + g_timeout # 更新超时时间,以当前78报文为准
                            self.packets[index].valid = False # 78报文设置无效标记
                            index += 1
                            continue
                        if (self.Calibrate(self.packets[cnt_sid], self.packets[index])): # 通过线程号等验证是否是对应的接收报文
                            cnt_rid = index # 找到了接收的报文
                            break
                    index += 1
    
                #rid未找到,超时
                if (-1 == cnt_rid):
                    continue
    
                #添加列表
                svc = Service(self.packets[cnt_sid].content_string, self.packets[cnt_rid].content_string)
                self.log.see(END)
                section.services.append(svc)
                self.packets[cnt_rid].valid = False
    
        # 创建xml文件
        def CreateFile(self, resultFile):
            impl = xml.dom.minidom.getDOMImplementation()
            # 设置根结点
            dom = impl.createDocument(None, 'ECU', None)
            root = dom.documentElement
            root.setAttribute("name", resultFile.name)
    
            # 根节点添加子节点COMMPARAMETERS
            commparameters = dom.createElement('COMMPARAMETERS')
            root.appendChild(commparameters)
    
            # 设置通讯参数
            for key, value in g_param.items():
                nameE=dom.createElement('PARAM')
                nameE.setAttribute("name", key)
                nameE.setAttribute("value", value)
                commparameters.appendChild(nameE)
        
            # 设置canid
            nameE=dom.createElement('PARAM')
            nameE.setAttribute("name", "CANSID")
            nameE.setAttribute("value",resultFile.sid)
            commparameters.appendChild(nameE)
    
            nameE=dom.createElement('PARAM')
            nameE.setAttribute("name", "CANRID")
            nameE.setAttribute("value", resultFile.sid)
            commparameters.appendChild(nameE)
    
            # 根节点添加子节点SECTIONS
            sections = dom.createElement('SECTIONS')
            root.appendChild(sections)
    
            # SECTION
            section=dom.createElement('SECTION')
            sections.appendChild(section)
    
            for svc in resultFile.services:
                #SERVICE
                service=dom.createElement('SERVICE')
                section.appendChild(service)
                #REQ
                req=dom.createElement('REQ')
                reqTxt=dom.createTextNode(svc.req)  #内容
                req.appendChild(reqTxt)
                service.appendChild(req)
                #RES
                res=dom.createElement('RES')
                resTxt=dom.createTextNode(svc.res)  #内容
                res.appendChild(resTxt)
                service.appendChild(res)
        
            f= open(resultFile.name + '.xml', 'w') #w替换为a,追加
            dom.writexml(f, addindent='	', newl='
    ')
            f.close()
    
    if __name__ == '__main__':
    	Main()
    

    打包程序

    # -w 隐藏控制台
    pyinstaller -F -w program.py
    

  • 相关阅读:
    Redis 补充
    python 魔法方法补充(__setattr__,__getattr__,__getattribute__)
    Mongodb 补充
    Mysql补充
    HTML
    优秀工具
    优秀文章收藏
    MySQL
    爬虫
    Python
  • 原文地址:https://www.cnblogs.com/xiongyungang/p/13577068.html
Copyright © 2011-2022 走看看