Приложение cx_Freeze закрывается сразу же без ошибок - PullRequest
0 голосов
/ 08 января 2019

Мое cx_Freeze приложение закрывается, когда я его открываю, и никаких ошибок не печатается. Установочный файл работает без ошибок. Я считаю, что это как-то связано с импортом в моем основном коде. Я использовал Python 3.6.5 cx_Freeze 6.0b1 и Windows 10.

setup.py

import os
from cx_Freeze import setup, Executable

include_lst = []

package_lst = ['numpy', 'scipy', 'pulp', 'pubsub', 'sqlite3', 'pandas',
               'wx', 'functools', 'sklearn', 'numpy.core._methods']

exclude_lst = ['matplotlib', 'tkinter', 'PyQt4.QtSql', 'PyQt5',
               'PyQt4.QtNetwork', 'PyQt4.QtScript', 'sqlalchemy']

base = None

setup (
       name='test',
       version='0.01',
       author='test',
       author_email='Omitted',
       options={'build_exe':
                   {'packages': package_lst,
                    'excludes': exclude_lst,
                    'include_files': include_lst
                   }
                },
       executables=[Executable('main_.py',  base=base, icon=icon_file)]
       )

Когда я замораживаю этот базовый пример, он работает без проблем

main.py

import wx


class MasterPage (wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.createFrame()

    def createFrame(self):
        self.width, self.height = wx.GetDisplaySize()
        self.SetTitle('Test')
        self.SetSize(wx.Size((self.width-50, self.height-50)))
        self.SetMinSize((1080, 720))
        self.W, self.H = self.GetSize()
        self.Bind(wx.EVT_CLOSE, self.onQuit)
        self.Centre()

    def onQuit(self, event):
        """Checks to make sure the user wants to leave the program"""
        dlg = wx.MessageDialog(self,'Do you really want to quit?',
                           'Confirm Exit',
                            wx.ICON_QUESTION|wx.OK|wx.CANCEL )
        result = dlg.ShowModal()
        dlg.Destroy
        if result == wx.ID_OK:
            self.Destroy()

if __name__.endswith('__main__'):
    app = wx.App()
    MasterPage(None).Show()
    app.MainLoop()

Но когда я добавляю import pandas или import <any module> над строкой import wx, приложение cx_Freeze закрывается, как только я его открываю

main.py

import pandas
import wx


class MasterPage (wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.createFrame()

    def createFrame(self):
        self.width, self.height = wx.GetDisplaySize()
        self.SetTitle('Test')
        self.SetSize(wx.Size((self.width-50, self.height-50)))
        self.SetMinSize((1080, 720))
        self.W, self.H = self.GetSize()
        self.Bind(wx.EVT_CLOSE, self.onQuit)
        self.Centre()

    def onQuit(self, event):
        """Checks to make sure the user wants to leave the program"""
        dlg = wx.MessageDialog(self,'Do you really want to quit?',
                           'Confirm Exit',
                            wx.ICON_QUESTION|wx.OK|wx.CANCEL )
        result = dlg.ShowModal()
        dlg.Destroy
        if result == wx.ID_OK:
            self.Destroy()

if __name__.endswith('__main__'):
    app = wx.App()
    MasterPage(None).Show()
    app.MainLoop()

Я также попытался поместить импорт в попытку, за исключением утверждения, что он все равно не откроется и ошибок нет.

main.py

try:
    import pandas
except Exception as e:
    print(e)
import wx


class MasterPage (wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.createFrame()

    def createFrame(self):
        self.width, self.height = wx.GetDisplaySize()
        self.SetTitle('Test')
        self.SetSize(wx.Size((self.width-50, self.height-50)))
        self.SetMinSize((1080, 720))
        self.W, self.H = self.GetSize()
        self.Bind(wx.EVT_CLOSE, self.onQuit)
        self.Centre()

    def onQuit(self, event):
        """Checks to make sure the user wants to leave the program"""
        dlg = wx.MessageDialog(self,'Do you really want to quit?',
                           'Confirm Exit',
                            wx.ICON_QUESTION|wx.OK|wx.CANCEL )
        result = dlg.ShowModal()
        dlg.Destroy
        if result == wx.ID_OK:
            self.Destroy()

if __name__.endswith('__main__'):
    app = wx.App()
    MasterPage(None).Show()
    app.MainLoop()

Я даже включил оператор print перед оператором import, а после оператора import запускается первый оператор печати, а затем приложение закрывается.

main.py

print('app started')
import pandas
print('import worked')
import wx


class MasterPage (wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.createFrame()

    def createFrame(self):
        self.width, self.height = wx.GetDisplaySize()
        self.SetTitle('Test')
        self.SetSize(wx.Size((self.width-50, self.height-50)))
        self.SetMinSize((1080, 720))
        self.W, self.H = self.GetSize()
        self.Bind(wx.EVT_CLOSE, self.onQuit)
        self.Centre()

    def onQuit(self, event):
        """Checks to make sure the user wants to leave the program"""
        dlg = wx.MessageDialog(self,'Do you really want to quit?',
                           'Confirm Exit',
                            wx.ICON_QUESTION|wx.OK|wx.CANCEL )
        result = dlg.ShowModal()
        dlg.Destroy
        if result == wx.ID_OK:
            self.Destroy()

if __name__.endswith('__main__'):
    app = wx.App()
    MasterPage(None).Show()
    app.MainLoop()

1 Ответ

0 голосов
/ 09 января 2019

Интересно, что похожий очевидный конфликт импорта между pandas и tkinter (вместо wx) был опубликован в Ошибка при создании исполняемого файла из скрипта Python3.6, импортирующего панд с использованием cx_Freeze .

  1. Я не знаком с wx. Прежде всего, я думаю, что вы должны использовать base = "Win32GUI" для приложения с графическим интерфейсом под Windows (см. Документацию cx_Freeze ). Замените base = None на следующие строки в вашем скрипте установки:

    # GUI applications require a different base on Windows (the default is for a console application).
    import sys
    base = None
    if sys.platform == "win32":
        base = "Win32GUI"
    
  2. Поскольку вы добавили scipy в список опций packages, вам также необходимо добавить scipy.spatial.cKDTree в список опций excludes (см. эту проблему ):

    exclude_lst = ['matplotlib', 'tkinter', 'PyQt4.QtSql', 'PyQt5',
                   'PyQt4.QtNetwork', 'PyQt4.QtScript', 'sqlalchemy',
                   'scipy.spatial.cKDTree']
    
  3. Вам также может понадобиться добавить sqlite3.dll в список опций include_files, чтобы иметь возможность использовать sqlite3 (я не уверен):

    PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
    include_lst = [(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'sqlite3.dll'), os.path.join('lib', 'sqlite3.dll'))]
    
  4. Наконец, я бы порекомендовал запустить ваше приложение из подсказки cmd, чтобы быть уверенным в получении всех сообщений об ошибках:

    • Запустить приглашение cmd (введите cmd в меню Пуск)
    • Перейдите в каталог сборки, в котором был создан замороженный исполняемый файл
    • Запустить замороженный исполняемый файл

Если вы все еще получаете сообщение об ошибке, добавьте его к своему вопросу.

...