文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Pyinstaller打包eel和pygame需要注意什么坑

2023-06-29 03:58

关注

本文小编为大家详细介绍“Pyinstaller打包eel和pygame需要注意什么坑”,内容详细,步骤清晰,细节处理妥当,希望这篇“Pyinstaller打包eel和pygame需要注意什么坑”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

1、打开cmd / Visual Studio等等可以装包的工具下载pyinstaller

如果是python环境,那么:pip install pyinstaller;如果是conda环境,那么:conda install pyinstaller

2、找到你的python_main程序

假设项目根目录为F:\xx\xx\xx,该目录的文件管理如下:

- Web(包括HTML、CSS、JS)- 游戏资源文件夹 (包括图片巴拉巴拉的)- Class1.py (Class1中导入Class3)- Class2.py- Class3.py- Python_Main.py (Python_Main中导入Class1,Class2和eel)

3、查看eel库

eel库一般在site-pakages里

Pyinstaller打包eel和pygame需要注意什么坑

打开__main__.py文件

#eel的__main__.py文件from __future__ import print_functionimport sysimport pkg_resources as pkgimport PyInstaller.__main__ as pyiimport osargs = sys.argv[1:]main_script = args.pop(0)web_folder = args.pop(0)print("Building executable with main script '%s' and web folder '%s'...\n" %      (main_script, web_folder))eel_js_file = pkg.resource_filename('eel', 'eel.js')js_file_arg = '%s%seel' % (eel_js_file, os.pathsep)web_folder_arg = '%s%s%s' % (web_folder, os.pathsep, web_folder)needed_args = ['--hidden-import', 'bottle_websocket',               '--add-data', js_file_arg, '--add-data', web_folder_arg]full_args = [main_script] + needed_args + argsprint('Running:\npyinstaller', ' '.join(full_args), '\n')pyi.run(full_args)

注意到print(“Building executable with main script ‘%s’ and web folder ‘%s’…\n” %

(main_script, web_folder))和print(‘Running:\npyinstaller’, ’ '.join(full_args), ‘\n’)可以知道eel的打包原理还是利用pyinstaller

4、打开cmd开始将含有eel的python_main打包起来

python -m eel F:\xx\xx\xx\Python_Main.py F:\xx\xx\xx\Web

这里暂时不加-w -f -i参数。(因为无论如何必然会出错) 报错,提示找不到eel.js文件。呼呼,我就奇怪了,eel.js文件不就在那儿摆着吗。打开eel的__init__.py文件查看

from __future__ import print_function   # Python 2 compatibility stufffrom builtins import rangefrom io import openimport gevent as gvtimport json as jsnimport bottle as btlimport bottle.ext.websocket as wbsimport re as rgximport osimport eel.browsers as brwimport random as rndimport sysimport pkg_resources as pkgimport socket_eel_js_file = pkg.resource_filename('eel', 'eel.js')_eel_js = open(_eel_js_file, encoding='utf-8').read()_websockets = []_call_return_values = {}_call_return_callbacks = {}_call_number = 0_exposed_functions = {}_js_functions = []_mock_queue = []_mock_queue_done = set()# All start() options must provide a default value and explanation here_start_args = {    'mode':             'chrome',                   # What browser is used    'host':             'localhost',                # Hostname use for Bottle server    'port':             8000,                       # Port used for Bottle server (use 0 for auto)    'block':            True,                       # Whether start() blocks calling thread    'jinja_templates':  None,                       # Folder for jinja2 templates    'cmdline_args':     ['--disable-http-cache'],   # Extra cmdline flags to pass to browser start    'size':             None,                       # (width, height) of main window    'position':         None,                       # (left, top) of main window    'geometry':         {},                         # Dictionary of size/position for all windows    'close_callback':   None,                       # Callback for when all windows have closed    'app_mode':  True,                              # (Chrome specific option)    'all_interfaces': False,                        # Allow bottle server to listen for connections on all interfaces    'disable_cache': True,                          # Sets the no-store response header when serving assets    'app': btl.default_app(),                       # Allows passing in a custom Bottle instance, e.g. with middleware}# == Temporary (suppressable) error message to inform users of breaking API change for v1.0.0 ===_start_args['suppress_error'] = Falseapi_error_message = '''----------------------------------------------------------------------------------  'options' argument deprecated in v1.0.0, see https://github.com/ChrisKnott/Eel  To suppress this error, add 'suppress_error=True' to start() call.  This option will be removed in future versions----------------------------------------------------------------------------------'''# ===============================================================================================# Public functionsdef expose(name_or_function=None):    # Deal with '@eel.expose()' - treat as '@eel.expose'    if name_or_function is None:        return expose    if type(name_or_function) == str:   # Called as '@eel.expose("my_name")'        name = name_or_function        def decorator(function):            _expose(name, function)            return function        return decorator    else:        function = name_or_function        _expose(function.__name__, function)        return functiondef init(path, allowed_extensions=['.js', '.html', '.txt', '.htm',                                   '.xhtml', '.vue']):    global root_path, _js_functions    root_path = _get_real_path(path)    js_functions = set()    for root, _, files in os.walk(root_path):        for name in files:            if not any(name.endswith(ext) for ext in allowed_extensions):                continue            try:                with open(os.path.join(root, name), encoding='utf-8') as file:                    contents = file.read()                    expose_calls = set()                    finder = rgx.findall(r'eel\.expose\(([^\)]+)\)', contents)                    for expose_call in finder:                        # If name specified in 2nd argument, strip quotes and store as function name                        if ',' in expose_call:                            expose_call = rgx.sub(r'["\']', '', expose_call.split(',')[1])                        expose_call = expose_call.strip()                        # Verify that function name is valid                        msg = "eel.expose() call contains '(' or '='"                        assert rgx.findall(r'[\(=]', expose_call) == [], msg                        expose_calls.add(expose_call)                    js_functions.update(expose_calls)            except UnicodeDecodeError:                pass    # Malformed file probably    _js_functions = list(js_functions)    for js_function in _js_functions:        _mock_js_function(js_function)def start(*start_urls, **kwargs):    _start_args.update(kwargs)    if 'options' in kwargs:        if _start_args['suppress_error']:            _start_args.update(kwargs['options'])        else:            raise RuntimeError(api_error_message)    if _start_args['port'] == 0:        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        sock.bind(('localhost', 0))        _start_args['port'] = sock.getsockname()[1]        sock.close()    if _start_args['jinja_templates'] != None:        from jinja2 import Environment, FileSystemLoader, select_autoescape        templates_path = os.path.join(root_path, _start_args['jinja_templates'])        _start_args['jinja_env'] = Environment(loader=FileSystemLoader(templates_path),                                 autoescape=select_autoescape(['html', 'xml']))    # Launch the browser to the starting URLs    show(*start_urls)    def run_lambda():        if _start_args['all_interfaces'] == True:            HOST = '0.0.0.0'        else:            HOST = _start_args['host']        app = _start_args['app']  # type: btl.Bottle        for route_path, route_params in BOTTLE_ROUTES.items():            route_func, route_kwargs = route_params            app.route(path=route_path, callback=route_func, **route_kwargs)        return btl.run(            host=HOST,            port=_start_args['port'],            server=wbs.GeventWebSocketServer,            quiet=True,            app=app)    # Start the webserver    if _start_args['block']:        run_lambda()    else:        spawn(run_lambda)def show(*start_urls):    brw.open(start_urls, _start_args)def sleep(seconds):    gvt.sleep(seconds)def spawn(function, *args, **kwargs):    gvt.spawn(function, *args, **kwargs)# Bottle Routesdef _eel():    start_geometry = {'default': {'size': _start_args['size'],                                  'position': _start_args['position']},                      'pages':   _start_args['geometry']}    page = _eel_js.replace('',                           '_py_functions: %s,' % list(_exposed_functions.keys()))    page = page.replace('',                        '_start_geometry: %s,' % _safe_json(start_geometry))    btl.response.content_type = 'application/javascript'    _set_response_headers(btl.response)    return pagedef _static(path):    response = None    if 'jinja_env' in _start_args and 'jinja_templates' in _start_args:        template_prefix = _start_args['jinja_templates'] + '/'        if path.startswith(template_prefix):            n = len(template_prefix)            template = _start_args['jinja_env'].get_template(path[n:])            response = btl.HTTPResponse(template.render())    if response is None:        response = btl.static_file(path, root=root_path)    _set_response_headers(response)    return responsedef _websocket(ws):    global _websockets    for js_function in _js_functions:        _import_js_function(js_function)    page = btl.request.query.page    if page not in _mock_queue_done:        for call in _mock_queue:            _repeated_send(ws, _safe_json(call))        _mock_queue_done.add(page)    _websockets += [(page, ws)]    while True:        msg = ws.receive()        if msg is not None:            message = jsn.loads(msg)            spawn(_process_message, message, ws)        else:            _websockets.remove((page, ws))            break    _websocket_close(page)BOTTLE_ROUTES = {    "/eel.js": (_eel, dict()),    "/<path:path>": (_static, dict()),    "/eel": (_websocket, dict(apply=[wbs.websocket]))}# Private functionsdef _safe_json(obj):    return jsn.dumps(obj, default=lambda o: None)def _repeated_send(ws, msg):    for attempt in range(100):        try:            ws.send(msg)            break        except Exception:            sleep(0.001)def _process_message(message, ws):    if 'call' in message:        return_val = _exposed_functions[message['name']](*message['args'])        _repeated_send(ws, _safe_json({ 'return': message['call'],                                        'value': return_val  }))    elif 'return' in message:        call_id = message['return']        if call_id in _call_return_callbacks:            callback = _call_return_callbacks.pop(call_id)            callback(message['value'])        else:            _call_return_values[call_id] = message['value']    else:        print('Invalid message received: ', message)def _get_real_path(path):    if getattr(sys, 'frozen', False):        return os.path.join(sys._MEIPASS, path)    else:        return os.path.abspath(path)def _mock_js_function(f):    exec('%s = lambda *args: _mock_call("%s", args)' % (f, f), globals())def _import_js_function(f):    exec('%s = lambda *args: _js_call("%s", args)' % (f, f), globals())def _call_object(name, args):    global _call_number    _call_number += 1    call_id = _call_number + rnd.random()    return {'call': call_id, 'name': name, 'args': args}def _mock_call(name, args):    call_object = _call_object(name, args)    global _mock_queue    _mock_queue += [call_object]    return _call_return(call_object)def _js_call(name, args):    call_object = _call_object(name, args)    for _, ws in _websockets:        _repeated_send(ws, _safe_json(call_object))    return _call_return(call_object)def _call_return(call):    call_id = call['call']    def return_func(callback=None):        if callback is not None:            _call_return_callbacks[call_id] = callback        else:            for w in range(10000):                if call_id in _call_return_values:                    return _call_return_values.pop(call_id)                sleep(0.001)    return return_funcdef _expose(name, function):    msg = 'Already exposed function with name "%s"' % name    assert name not in _exposed_functions, msg    _exposed_functions[name] = functiondef _websocket_close(page):    close_callback = _start_args.get('close_callback')    if close_callback is not None:        sockets = [p for _, p in _websockets]        close_callback(page, sockets)    else:        # Default behaviour - wait 1s, then quit if all sockets are closed        sleep(1.0)        if len(_websockets) == 0:            sys.exit()def _set_response_headers(response):    if _start_args['disable_cache']:        # https://stackoverflow.com/a/24748094/280852        response.set_header('Cache-Control', 'no-store')

注意到了吗?代码中有这样两句:

_eel_js_file = pkg.resource_filename('eel', 'eel.js')_eel_js = open(_eel_js_file, encoding='utf-8').read()

一不做,二不休,把eel.js的内容复制下来,然后,奥里给。将代码做如下修改(即贴即用)

from __future__ import print_function   # Python 2 compatibility stufffrom builtins import rangefrom io import openimport gevent as gvtimport json as jsnimport bottle as btlimport bottle.ext.websocket as wbsimport re as rgximport osimport eel.browsers as brwimport random as rndimport sysimport pkg_resources as pkgimport socketeelJS = '''eel = {    _host: window.location.origin,    set_host: function (hostname) {        eel._host = hostname    },    expose: function(f, name) {        if(name === undefined){            name = f.toString();            let i = 'function '.length, j = name.indexOf('(');            name = name.substring(i, j).trim();        }        eel._exposed_functions[name] = f;    },    guid: function() {        return eel._guid;    },    // These get dynamically added by library when file is served            _guid: ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>            (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)        ),    _exposed_functions: {},    _mock_queue: [],    _mock_py_functions: function() {        for(let i = 0; i < eel._py_functions.length; i++) {            let name = eel._py_functions[i];            eel[name] = function() {                let call_object = eel._call_object(name, arguments);                eel._mock_queue.push(call_object);                return eel._call_return(call_object);            }        }    },    _import_py_function: function(name) {        let func_name = name;        eel[name] = function() {            let call_object = eel._call_object(func_name, arguments);            eel._websocket.send(eel._toJSON(call_object));            return eel._call_return(call_object);        }    },    _call_number: 0,    _call_return_callbacks: {},    _call_object: function(name, args) {        let arg_array = [];        for(let i = 0; i < args.length; i++){            arg_array.push(args[i]);        }        let call_id = (eel._call_number += 1) + Math.random();        return {'call': call_id, 'name': name, 'args': arg_array};    },    _sleep: function(ms) {        return new Promise(resolve => setTimeout(resolve, ms));    },    _toJSON: function(obj) {        return JSON.stringify(obj, (k, v) => v === undefined ? null : v);    },    _call_return: function(call) {        return function(callback = null) {            if(callback != null) {                eel._call_return_callbacks[call.call] = callback;            } else {                return new Promise(function(resolve) {                    eel._call_return_callbacks[call.call] = resolve;                });            }        }    },    _position_window: function(page) {        let size = eel._start_geometry【'default'】.size;        let position = eel._start_geometry['default'].position;        if(page in eel._start_geometry.pages) {            size = eel._start_geometry.pages【page】.size;            position = eel._start_geometry.pages【page】.position;        }        if(size != null){            window.resizeTo(size[0], size[1]);        }        if(position != null){            window.moveTo(position[0], position[1]);        }    },    _init: function() {        eel._mock_py_functions();        document.addEventListener("DOMContentLoaded", function(event) {            let page = window.location.pathname.substring(1);            eel._position_window(page);            let websocket_addr = (eel._host + '/eel').replace('http', 'ws');            websocket_addr += ('?page=' + page);            eel._websocket = new WebSocket(websocket_addr);            eel._websocket.onopen = function() {                for(let i = 0; i < eel._py_functions.length; i++){                    let py_function = eel._py_functions[i];                    eel._import_py_function(py_function);                }                while(eel._mock_queue.length > 0) {                    let call = eel._mock_queue.shift();                    eel._websocket.send(eel._toJSON(call));                }            };            eel._websocket.onmessage = function (e) {                let message = JSON.parse(e.data);                if(message.hasOwnProperty('call') ) {                    // Python making a function call into us                    if(message.name in eel._exposed_functions) {                        let return_val = eel._exposed_functions[message.name](...message.args);                        eel._websocket.send(eel._toJSON({'return': message.call, 'value': return_val}));                    }                } else if(message.hasOwnProperty('return')) {                    // Python returning a value to us                    if(message['return'] in eel._call_return_callbacks) {                        eel._call_return_callbacks[message['return']](message.value);                    }                } else {                    throw 'Invalid message ' + message;                }            };        });    }}eel._init();if(typeof require !== 'undefined'){    // Avoid name collisions when using Electron, so jQuery etc work normally    window.nodeRequire = require;    delete window.require;    delete window.exports;    delete window.module;}'''try:_eel_js_file = pkg.resource_filename('eel', 'eel.js')_eel_js = open(_eel_js_file, encoding='utf-8').read()except:_eel_js = eelJS_websockets = []_call_return_values = {}_call_return_callbacks = {}_call_number = 0_exposed_functions = {}_js_functions = []_mock_queue = []_mock_queue_done = set()# All start() options must provide a default value and explanation here_start_args = {    'mode':             'chrome',                   # What browser is used    'host':             'localhost',                # Hostname use for Bottle server    'port':             8000,                       # Port used for Bottle server (use 0 for auto)    'block':            True,                       # Whether start() blocks calling thread    'jinja_templates':  None,                       # Folder for jinja2 templates    'cmdline_args':     ['--disable-http-cache'],   # Extra cmdline flags to pass to browser start    'size':             None,                       # (width, height) of main window    'position':         None,                       # (left, top) of main window    'geometry':         {},                         # Dictionary of size/position for all windows    'close_callback':   None,                       # Callback for when all windows have closed    'app_mode':  True,                              # (Chrome specific option)    'all_interfaces': False,                        # Allow bottle server to listen for connections on all interfaces    'disable_cache': True,                          # Sets the no-store response header when serving assets    'app': btl.default_app(),                       # Allows passing in a custom Bottle instance, e.g. with middleware}# == Temporary (suppressable) error message to inform users of breaking API change for v1.0.0 ===_start_args['suppress_error'] = Falseapi_error_message = '''----------------------------------------------------------------------------------  'options' argument deprecated in v1.0.0, see https://github.com/ChrisKnott/Eel  To suppress this error, add 'suppress_error=True' to start() call.  This option will be removed in future versions----------------------------------------------------------------------------------'''# ===============================================================================================# Public functionsdef expose(name_or_function=None):    # Deal with '@eel.expose()' - treat as '@eel.expose'    if name_or_function is None:        return expose    if type(name_or_function) == str:   # Called as '@eel.expose("my_name")'        name = name_or_function        def decorator(function):            _expose(name, function)            return function        return decorator    else:        function = name_or_function        _expose(function.__name__, function)        return functiondef init(path, allowed_extensions=['.js', '.html', '.txt', '.htm',                                   '.xhtml', '.vue']):    global root_path, _js_functions    root_path = _get_real_path(path)    js_functions = set()    for root, _, files in os.walk(root_path):        for name in files:            if not any(name.endswith(ext) for ext in allowed_extensions):                continue            try:                with open(os.path.join(root, name), encoding='utf-8') as file:                    contents = file.read()                    expose_calls = set()                    finder = rgx.findall(r'eel\.expose\(([^\)]+)\)', contents)                    for expose_call in finder:                        # If name specified in 2nd argument, strip quotes and store as function name                        if ',' in expose_call:                            expose_call = rgx.sub(r'["\']', '', expose_call.split(',')[1])                        expose_call = expose_call.strip()                        # Verify that function name is valid                        msg = "eel.expose() call contains '(' or '='"                        assert rgx.findall(r'[\(=]', expose_call) == [], msg                        expose_calls.add(expose_call)                    js_functions.update(expose_calls)            except UnicodeDecodeError:                pass    # Malformed file probably    _js_functions = list(js_functions)    for js_function in _js_functions:        _mock_js_function(js_function)def start(*start_urls, **kwargs):    _start_args.update(kwargs)    if 'options' in kwargs:        if _start_args['suppress_error']:            _start_args.update(kwargs['options'])        else:            raise RuntimeError(api_error_message)    if _start_args['port'] == 0:        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        sock.bind(('localhost', 0))        _start_args['port'] = sock.getsockname()[1]        sock.close()    if _start_args['jinja_templates'] != None:        from jinja2 import Environment, FileSystemLoader, select_autoescape        templates_path = os.path.join(root_path, _start_args['jinja_templates'])        _start_args['jinja_env'] = Environment(loader=FileSystemLoader(templates_path),                                 autoescape=select_autoescape(['html', 'xml']))    # Launch the browser to the starting URLs    show(*start_urls)    def run_lambda():        if _start_args['all_interfaces'] == True:            HOST = '0.0.0.0'        else:            HOST = _start_args['host']        app = _start_args['app']  # type: btl.Bottle        for route_path, route_params in BOTTLE_ROUTES.items():            route_func, route_kwargs = route_params            app.route(path=route_path, callback=route_func, **route_kwargs)        return btl.run(            host=HOST,            port=_start_args['port'],            server=wbs.GeventWebSocketServer,            quiet=True,            app=app)    # Start the webserver    if _start_args['block']:        run_lambda()    else:        spawn(run_lambda)def show(*start_urls):    brw.open(start_urls, _start_args)def sleep(seconds):    gvt.sleep(seconds)def spawn(function, *args, **kwargs):    gvt.spawn(function, *args, **kwargs)# Bottle Routesdef _eel():    start_geometry = {'default': {'size': _start_args['size'],                                  'position': _start_args['position']},                      'pages':   _start_args['geometry']}    page = _eel_js.replace('',                           '_py_functions: %s,' % list(_exposed_functions.keys()))    page = page.replace('',                        '_start_geometry: %s,' % _safe_json(start_geometry))    btl.response.content_type = 'application/javascript'    _set_response_headers(btl.response)    return pagedef _static(path):    response = None    if 'jinja_env' in _start_args and 'jinja_templates' in _start_args:        template_prefix = _start_args['jinja_templates'] + '/'        if path.startswith(template_prefix):            n = len(template_prefix)            template = _start_args['jinja_env'].get_template(path[n:])            response = btl.HTTPResponse(template.render())    if response is None:        response = btl.static_file(path, root=root_path)    _set_response_headers(response)    return responsedef _websocket(ws):    global _websockets    for js_function in _js_functions:        _import_js_function(js_function)    page = btl.request.query.page    if page not in _mock_queue_done:        for call in _mock_queue:            _repeated_send(ws, _safe_json(call))        _mock_queue_done.add(page)    _websockets += [(page, ws)]    while True:        msg = ws.receive()        if msg is not None:            message = jsn.loads(msg)            spawn(_process_message, message, ws)        else:            _websockets.remove((page, ws))            break    _websocket_close(page)BOTTLE_ROUTES = {    "/eel.js": (_eel, dict()),    "/<path:path>": (_static, dict()),    "/eel": (_websocket, dict(apply=[wbs.websocket]))}# Private functionsdef _safe_json(obj):    return jsn.dumps(obj, default=lambda o: None)def _repeated_send(ws, msg):    for attempt in range(100):        try:            ws.send(msg)            break        except Exception:            sleep(0.001)def _process_message(message, ws):    if 'call' in message:        return_val = _exposed_functions[message['name']](*message['args'])        _repeated_send(ws, _safe_json({ 'return': message['call'],                                        'value': return_val  }))    elif 'return' in message:        call_id = message['return']        if call_id in _call_return_callbacks:            callback = _call_return_callbacks.pop(call_id)            callback(message['value'])        else:            _call_return_values[call_id] = message['value']    else:        print('Invalid message received: ', message)def _get_real_path(path):    if getattr(sys, 'frozen', False):        return os.path.join(sys._MEIPASS, path)    else:        return os.path.abspath(path)def _mock_js_function(f):    exec('%s = lambda *args: _mock_call("%s", args)' % (f, f), globals())def _import_js_function(f):    exec('%s = lambda *args: _js_call("%s", args)' % (f, f), globals())def _call_object(name, args):    global _call_number    _call_number += 1    call_id = _call_number + rnd.random()    return {'call': call_id, 'name': name, 'args': args}def _mock_call(name, args):    call_object = _call_object(name, args)    global _mock_queue    _mock_queue += [call_object]    return _call_return(call_object)def _js_call(name, args):    call_object = _call_object(name, args)    for _, ws in _websockets:        _repeated_send(ws, _safe_json(call_object))    return _call_return(call_object)def _call_return(call):    call_id = call['call']    def return_func(callback=None):        if callback is not None:            _call_return_callbacks[call_id] = callback        else:            for w in range(10000):                if call_id in _call_return_values:                    return _call_return_values.pop(call_id)                sleep(0.001)    return return_funcdef _expose(name, function):    msg = 'Already exposed function with name "%s"' % name    assert name not in _exposed_functions, msg    _exposed_functions[name] = functiondef _websocket_close(page):    close_callback = _start_args.get('close_callback')    if close_callback is not None:        sockets = [p for _, p in _websockets]        close_callback(page, sockets)    else:        # Default behaviour - wait 1s, then quit if all sockets are closed        sleep(1.0)        if len(_websockets) == 0:            sys.exit()def _set_response_headers(response):    if _start_args['disable_cache']:        # https://stackoverflow.com/a/24748094/280852        response.set_header('Cache-Control', 'no-store')

ok,下面在运行一次cmd,执行之前的代码,不报错了。但是,这次又遇到了新的问题。

'utf-8' codec can't decode byte 0xce

woc。这编码怎么又出了问题。百度一下,找到了解决方案。在cmd中先输入

chcp 65001

然后再执行

python -m eel F:\xx\xx\xx\Python_Main.py F:\xx\xx\xx\Web

这下总算是成功打包了。

5、找到我们的Python_Main.exe文件

打包后的文件一般在cmd的启动路径下能够找到。如,我的Python_Main.exe文件就应该在C:\Users\Deadpool里

Pyinstaller打包eel和pygame需要注意什么坑

发现在Deadpool文件里多出了三个文件,分别是Python_Main.spec, distbuild。打开dist后,发现有一个Python_Main文件夹,打开,便能找到Python_Main.exe,点击,弹出小黑框。接着,恭喜你,主界面显示404 Not Found。What?Woc。又是什么问题,难道我需要把Web文件夹移到这个Python_Main文件夹里?经验证答案是“是”。事实上,我们需要把所有文件都移到这个Python_Main里面,也就是前面的Web以及游戏资源文件夹。OK,问题解决。感动啊 (ಥ _ ಥ)~~~~当我满怀激情的点击了开始游戏,小黑框里又一个错误出现了:

pygame.error: Couldn't open xxx\xxx.png

百度一下,原来需要用pyinstaller打包时,pygame的load图片必须用绝对路径。ok,那就只有修改代码,重新打包。问题解决。接下来,就是如何处理掉小黑框了。现在,先让我们看看Python_Main.spec文件:

# -*- mode: python ; coding: utf-8 -*-block_cipher = Nonea = Analysis(['F:\\xx\\xx\\Python_Main.py'],             pathex=['C:\\Users\\Deadpool'],             binaries=[],             datas=[('F:\\AnocondaApp\\lib\\site-packages\\eel\\eel.js', 'eel'), ('F:\\xx\\xx\\Web', 'F:\\xx\\xx\\Web')],             hiddenimports=['bottle_websocket'],             hookspath=[],             runtime_hooks=[],             excludes=[],             win_no_prefer_redirects=False,             win_private_assemblies=False,             cipher=block_cipher,             noarchive=False)pyz = PYZ(a.pure, a.zipped_data,             cipher=block_cipher)exe = EXE(pyz,          a.scripts,          [],          exclude_binaries=True,          name='Python_Main',          debug=False,          bootloader_ignore_signals=False,          strip=False,          upx=True,          console=True, icon='')coll = COLLECT(exe,               a.binaries,               a.zipfiles,               a.datas,               strip=False,               upx=True,               upx_exclude=[],               name='Python_Main')

简单分析后,把console = True改为console = False,咦,这里还有一个icon,应该不会是游戏图标吧,试着改改,于是我让icon = F:\xx\xx\Web\favicon.ico。改完后,保存。

如何运行spec文件呢?无所不能的网友给出了答案。

chcp 65001pyinstaller Python_Main.spec

读到这里,这篇“Pyinstaller打包eel和pygame需要注意什么坑”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯