lawrence1357 发表于 2020-8-3 23:17:12

pyinstaller

为什么用pyinstaller -D -w Main.py打包完成后,运行dist里面的Main.exe会弹窗Failed to execute script main
图片是打包的过程,下面是代码,请帮忙看看问题出在哪
from tkinter import *
from tkinter.messagebox import *


class Client:
    def __init__(self, root, username):
      self.username = username
      self.root = root
      self.root.title('客户信息-查询系统')
      self.root.minsize(960, 560)
      self.root.maxsize(960, 560)
      self.root.geometry('960x560+360-180')
      self.createpage()
      clients_info = self.find()
      self.clear_text()
      new_clients = []
      information = ''
      for clients in clients_info:
            if clients != '\n':
                new_clients.append(clients)
      for new_client in new_clients:
            information = '客户姓名:' + new_client.split(',') + '\t' + '客户电话:' + new_client.split(',')[
                1] + '\t' + '客户证件号码:' + new_client.split(',') + '\t' + '销售员:' + \
                        new_client.split(',')
            self.text.insert(END, information)

    def createpage(self):
      self.frame = Frame(self.root)
      self.frame.pack(fill=BOTH)

      Label(self.frame, text='通过姓名查询:').grid(row=0, column=0, padx=5, pady=5)
      self.name = StringVar()
      Entry(self.frame, textvariable=self.name).grid(row=0, column=1, padx=5, pady=5)
      Button(self.frame, text='查询', command=self.namefind).grid(row=0, column=2, padx=5, pady=5)

      Label(self.frame, text='通过电话查询:').grid(row=0, column=3, padx=5, pady=5)
      self.phone = StringVar()
      Entry(self.frame, textvariable=self.phone).grid(row=0, column=4, padx=5, pady=5)
      Button(self.frame, text='查询', command=self.phonefind).grid(row=0, column=5, padx=5, pady=5)

      Label(self.frame, text='通过证件查询:').grid(row=0, column=6, padx=5, pady=5)
      self.id_nub = StringVar()
      Entry(self.frame, textvariable=self.id_nub).grid(row=0, column=7, padx=5, pady=5)
      Button(self.frame, text='查询', command=self.idfind).grid(row=0, column=8, padx=5, pady=5)

      self.text = Text(self.frame)
      self.text.grid(row=1, column=0, columnspan=9, ipadx=192, ipady=80, padx=5, pady=5,
                     sticky=NSEW)

    def find(self):
      with open(r'clients/client.txt', encoding='UTF-8')as client_info:
            clients = client_info.readlines()
            return clients

    def namefind(self):
      new_name = self.name.get().strip()
      self.clear_text()
      self.clear_entry()
      if new_name:
            clients = self.find()
            new_clients = []
            names = []
            for client in clients:
                if client != '\n':
                  new_clients.append(client)
                  names.append(client.split(','))
            if new_name in names:
                information = ''
                for new_client in new_clients:
                  if new_name == new_client.split(','):
                        information += '客户姓名:' + new_client.split(',') + '\t' + '客户电话:' + new_client.split(',')[
                            1] + '\t' + '客户证件号码:' + new_client.split(',') + '\t' + '销售员:' + \
                                       new_client.split(',')
                        self.text.insert(END, information)
                  information = ''
            else:
                showinfo(title='错误', message='未录入此客户!')
      else:
            showinfo(title='错误', message='查询索引不能空!')

    def phonefind(self):
      new_phone = self.phone.get().strip()
      self.clear_text()
      self.clear_entry()
      if new_phone:
            if len(new_phone) == 11:
                clients = self.find()
                new_clients = []
                phones = []
                for client in clients:
                  if client != '\n':
                        new_clients.append(client)
                        phones.append(client.split(','))
                if new_phone in phones:
                  information = ''
                  for new_client in new_clients:
                        if new_phone == new_client.split(','):
                            information += '客户姓名:' + new_client.split(',') + '\t' + '客户电话:' + new_client.split(',')[
                              1] + '\t' + '客户证件号码:' + new_client.split(',') + '\t' + '销售员:' + \
                                           new_client.split(',')
                            self.text.insert(END, information)
                        information = ''
                else:
                  showinfo(title='错误', message='未录入此号码!')
            else:
                showinfo(title='错误', message='输入号码错误!')
      else:
            showinfo(title='错误', message='查询索引不能空!')

    def idfind(self):
      new_id = self.id_nub.get().strip()
      self.clear_text()
      self.clear_entry()
      if new_id:
            if len(new_id) == 18 or new_id == '未录入':
                clients = self.find()
                new_clients = []
                ids = []
                for client in clients:
                  if client != '\n':
                        new_clients.append(client)
                        ids.append(client.split(','))
                if new_id in ids:
                  information = ''
                  for new_client in new_clients:
                        if new_id == new_client.split(','):
                            information += '客户姓名:' + new_client.split(',') + '\t' + '客户电话:' + new_client.split(',')[
                              1] + '\t' + '客户证件号码:' + new_client.split(',') + '\t' + '销售员:' + \
                                           new_client.split(',')
                            self.text.insert(END, information)
                        information = ''
                else:
                  showinfo(title='错误', message='未录入此证件号!')
            else:
                showinfo(title='错误', message='输入证件号错误!')
      else:
            showinfo(title='错误', message='查询索引不能空!')

    def clear_text(self):
      self.text.delete(0.0, END)

    def clear_entry(self):
      self.name.set('')
      self.phone.set('')
      self.id_nub.set('')

from tkinter import *
from tkinter.messagebox import *
from Client import *


class EnterPage:
    def __init__(self, mainpage, username):
      self.root = mainpage
      self.username = username
      self.root.title('客户信息-录入系统')
      self.root.minsize(560, 256)
      self.root.maxsize(560, 256)
      self.root.geometry('560x256+480-380')
      self.createpage()

    def createpage(self):
      self.frame = Frame(self.root)
      self.frame.pack()

      Label(self.frame).grid(row=0, rowspan=2)
      Label(self.frame, text='客户姓名:', font=('幼圆', 11)).grid(row=4, column=0, pady=10, sticky=E)
      self.client_name = StringVar()
      Entry(self.frame, textvariable=self.client_name).grid(row=4, column=1, columnspan=3, ipadx=20)
      Label(self.frame, text='*', font=('幼圆', 10), fg='red').grid(row=4, column=4, pady=10, sticky=E)
      Label(self.frame, text='客户电话:', font=('幼圆', 11)).grid(row=5, column=0, pady=10, sticky=E)
      self.client_phone = StringVar()
      Entry(self.frame, textvariable=self.client_phone).grid(row=5, column=1, columnspan=3, ipadx=20)
      Label(self.frame, text='*', font=('幼圆', 10), fg='red').grid(row=5, column=4, pady=10, sticky=E)
      Label(self.frame, text='客户证件号:', font=('幼圆', 11)).grid(row=6, column=0, pady=10, sticky=E)
      self.client_id = StringVar()
      Entry(self.frame, textvariable=self.client_id).grid(row=6, column=1, columnspan=3, ipadx=20)
      Label(self.frame, text='销售员:', font=('幼圆', 11)).grid(row=7, column=0, pady=10, sticky=E)
      self.salesman = StringVar()
      Entry(self.frame, textvariable=self.salesman, state='readonly').grid(row=7, column=1, columnspan=3, ipadx=20)
      self.salesman.set(self.username)
      Button(self.frame, text='保存', command=self.save).grid(row=8, column=1, pady=10, ipadx=10)
      Button(self.frame, text='查询', command=self.find).grid(row=8, column=2, pady=10, ipadx=10)
      Button(self.frame, text='退出', command=quit).grid(row=8, column=3, pady=10, ipadx=10)

    def save(self):
      if not (self.client_name.get() and self.client_phone.get()):
            if not self.client_name.get() and self.client_phone.get():
                showinfo(title='错误', message='客户姓名为必填项!')
            elif self.client_name.get() and not self.client_phone.get():
                showinfo(title='错误', message='客户电话为必填项!')
            else:
                showinfo(title='错误', message='*号为必填项!')
      else:
            if self.client_phone.get().isdigit() and len(self.client_phone.get()) == 11:
                client_id = self.client_id.get()
                if not client_id:
                  client_id = '未录入'
                  with open(r'clients/client.txt', encoding='UTF-8')as client_info:
                        clients = client_info.readlines()
                        for client in clients:
                            if client != '\n':
                              if client.split(',') == self.client_phone.get():
                                    salesman = re.search(r'.*', client.split(',')).group()
                                    showinfo(title='错误',
                                             message='手机号为"{}"的客户已存在,登记姓名为"{}",录入人员"{}"!'.format(
                                                 self.client_phone.get(),
                                                 client.split(','),
                                                 salesman))
                                    self.clear_entry()
                                    break
                        else:
                            with open(r'clients/client.txt', 'a', encoding='UTF-8')as client:
                              client.write(
                                    '{},{},{},{}\n'.format(self.client_name.get(), self.client_phone.get(),
                                                         client_id, self.salesman.get()))
                              showinfo(title='提示', message='保存成功!')
                              self.clear_entry()

                else:
                  if len(self.client_id.get()) == 18:
                        with open(r'clients/client.txt', encoding='UTF-8')as client_info:
                            clients = client_info.readlines()
                            for client in clients:
                              if client != '\n':
                                    salesman = re.search(r'.*', client.split(',')).group()
                                    if client.split(',') == self.client_phone.get() or client.split(',')[
                                        2] == self.client_id.get():
                                        if client.split(',') == self.client_phone.get() and client.split(',')[
                                          2] == self.client_id.get():
                                          showinfo(title='错误',
                                                   message='手机号为"{}",证件号为"{}"的客户已存在,登记姓名为"{}",录入人员"{}"!'.format(
                                                         self.client_phone.get(), self.client_id.get(),
                                                         client.split(','),
                                                         salesman))
                                          self.clear_entry()
                                          break
                                        elif client.split(',') == self.client_phone.get() and client.split(',')[
                                          2] != self.client_id.get():
                                          showinfo(title='错误',
                                                   message='手机号为"{}"的客户已存在,登记姓名为"{}",录入人员"{}"!'.format(
                                                         self.client_phone.get(), client.split(','), salesman))
                                          self.clear_entry()
                                          break
                                        elif client.split(',') != self.client_phone.get() and client.split(',')[
                                          2] == self.client_id.get():
                                          showinfo(title='错误',
                                                   message='证件号为"{}"的客户已存在,登记姓名为"{}",录入人员"{}"!'.format(
                                                         self.client_id.get(), client.split(','), salesman))
                                          self.clear_entry()
                                          break

                            else:
                              with open(r'clients/client.txt', 'a', encoding='UTF-8')as client:
                                    client.write(
                                        '{},{},{},{}\n'.format(self.client_name.get(), self.client_phone.get(),
                                                               client_id, self.salesman.get()))
                                    showinfo(title='提示', message='保存成功!')
                                    self.clear_entry()
                  else:
                        showinfo(title='错误', message='证件号码错误!')
            else:
                showinfo(title='错误', message='电话号码错误!')
                self.client_phone.set('')

    def find(self):
      self.frame.destroy()
      Client(self.root, self.username)

    def clear_entry(self):
      self.client_name.set('')
      self.client_phone.set('')
      self.client_id.set('')

from tkinter import *
from tkinter.messagebox import *
import re
from EnterPage import *


class LoginPage:
    def __init__(self, loginroot):
      self.root = loginroot
      self.root.title('登录')
      self.root.minsize(360, 180)
      self.root.maxsize(360, 180)
      self.root.geometry('360x180+550-350')
      self.createpage()

    def createpage(self):
      self.frame = Frame(self.root)
      self.frame.pack()
      Label(self.frame, text='用户名:', font=('幼圆', 11)).grid(row=0, sticky=W)
      self.username = StringVar()
      Entry(self.frame, textvariable=self.username).grid(row=0, column=1, columnspan=3, pady=20, ipadx=30, sticky=W)
      Label(self.frame, text='密码:', font=('幼圆', 11)).grid(row=1, stick=W, pady=10)
      self.password = StringVar()
      Entry(self.frame, textvariable=self.password, show='*').grid(row=1, column=1, columnspan=3, pady=10, ipadx=30,
                                                                     sticky=W)
      Button(self.frame, text='登录', command=self.logincheck).grid(row=2, column=1, ipadx=10)
      Button(self.frame, text='注册', command=self.register).grid(row=2, column=2, ipadx=10)
      Button(self.frame, text='取消', command=quit).grid(row=2, column=3, ipadx=10)

    def logincheck(self):
      with open(r'users/users.txt', encoding='UTF-8')as users_name_password:
            users = users_name_password.readlines()
            if users:
                name = []
                for user in users:
                  name.append(user.split(','))
                if self.username.get() and self.password.get():
                  if self.username.get() in name:
                        for user in users:
                            if self.username.get() == user.split(','):
                              password = re.search(r'.*', user.split(',')).group()
                              if self.password.get() == password:
                                    self.clear_entry()
                                    self.frame.destroy()
                                    EnterPage(self.root, user.split(','))
                                    break
                              else:
                                    self.clear_entry()
                                    showinfo(title='错误', message='用户名或密码不正确!')
                                    break
                  else:
                        self.name_notfound()
                else:
                  showinfo(title='错误', message='用户名或密码不能为空!')
            else:
                self.name_notfound()

    def register(self):
      if not (self.username.get() and self.password.get()):
            showinfo(title='错误', message='用户名或密码不能为空!')
      else:
            with open(r'users/users.txt', encoding='UTF-8')as users_name_password:
                users = users_name_password.readlines()
                if users:
                  for user in users:
                        username = user.split(',')
                        if self.username.get() == username:
                            showinfo(title='提示', message='用户名"{}"已存在!'.format(username))
                            self.clear_entry()
                            break
                  else:
                        self.write_file()
                else:
                  self.write_file()

    def write_file(self):
      with open(r'users/users.txt', 'a', encoding='UTF-8')as users:
            users.write('{},{}\n'.format(self.username.get(), self.password.get()))
      self.clear_entry()
      showinfo(title='提示', message='注册成功!')

    def name_notfound(self):
      showinfo(title='错误', message='用户名"{}"不存在!'.format(self.username.get()))
      self.clear_entry()

    def clear_entry(self):
      self.username.set('')
      self.password.set('')

from tkinter import *
from LoginPage import *


if __name__ == '__main__':
    root = Tk()
    LoginPage(root)
    root.mainloop()

Twilight6 发表于 2020-8-3 23:34:28

试试打包:pyinstaller -F -w Main.py

kaixin9611 发表于 2020-8-4 00:19:03

控制台程序生成EXE命令:
pyinstaller -F 文件名.py窗口类程序生成EXE命令:
pyinstaller -Fw 文件名.py
否则就会出现你现在的情况。


BSOD 发表于 2020-8-8 22:09:33

不用看代码, 目测是项目路径导致的, 由于Pyinstaller在打包时, 项目路径如果不指定可能会被偏移到/temp路径下, 所以在import的时候就找不到对应的模块了
所以对于打包程序, 项目中不能使用相对路径, 而且BASE_DIR需要进行绑定, 推荐在入口文件中增加:
import os
import sys

BASE_DIR = os.path.dirname(sys.argv)
sys.path.insert(0, BASE_DIR)
print(BASE_DIR)
项目中相对路径应该引用BASE_DIR调整为绝对路径, 否则生成文件你将会找不到在哪

陈尚涵 发表于 2020-8-10 10:42:29

BSOD 发表于 2020-8-8 22:09
不用看代码, 目测是项目路径导致的, 由于Pyinstaller在打包时, 项目路径如果不指定可能会被偏移到/temp路径 ...

貌似不需要这么麻烦,放到lite-packages里面不就行了吗{:10_256:}

悠悠2264 发表于 2020-8-10 12:33:30

代码相对路径不对,将打包后的exe文件放到main.py的那个文件夹下即可运行
页: [1]
查看完整版本: pyinstaller