返回顶部
首页 > 资讯 > 精选 >Pyinstaller打包eel和pygame需要注意什么坑
  • 111
分享到

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

2023-06-29 03:06:36 111人浏览 薄情痞子
摘要

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

本文小编为大家详细介绍“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(包括htmlCSSjs)- 游戏资源文件夹 (包括图片巴拉巴拉的)- 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需要注意什么坑”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

--结束END--

本文标题: Pyinstaller打包eel和pygame需要注意什么坑

本文链接: https://lsjlt.com/news/322277.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Pyinstaller打包eel和pygame需要注意什么坑
    本文小编为大家详细介绍“Pyinstaller打包eel和pygame需要注意什么坑”,内容详细,步骤清晰,细节处理妥当,希望这篇“Pyinstaller打包eel和pygame需要注意什么坑”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢...
    99+
    2023-06-29
  • 关于Pyinstaller打包eel和pygame需要注意的坑
    这几天我们团队用python做了一个游戏,引擎用的pygame,UI界面用的eel(一个python库,用于利用HTML开发桌面应用程序,主要是因为QT机制太过复杂,而博主Deadp...
    99+
    2024-04-02
  • Java 打包 NumPy 和 Django 的坑点有哪些需要注意?
    在 Java 开发中,我们常常需要将 Python 库打包到 Java 项目中。本文将重点讲解在 Java 项目中打包 NumPy 和 Django 库时需要注意的坑点。 NumPy 库的打包 NumPy 是 Python 中用于科学...
    99+
    2023-09-04
    打包 numy django
  • 用 ASP 和 Django 打包 NPM,有什么需要注意的吗?
    在今天的软件开发领域中,前端和后端分离的架构已经成为主流,前端开发者经常会使用 NPM 包管理器来管理前端依赖的包。但是,在某些情况下,我们可能需要将前端的依赖包打包到后端的代码中。这时,我们就需要用到 ASP.NET 和 Django 这...
    99+
    2023-11-15
    npm 打包 django
  • Go 和 Laravel 中的打包和重定向:有什么需要注意的吗?
    Go 和 Laravel 是两个非常流行的编程语言和框架,它们都提供了一些非常有用的功能,比如打包和重定向。在本文中,我们将探讨在 Go 和 Laravel 中打包和重定向的一些注意事项。 一、Go 中的打包和重定向 打包 打包是指将多...
    99+
    2023-08-03
    laravel 打包 重定向
  • 域名和SEO需要注意什么
    这篇文章主要为大家展示了“域名和SEO需要注意什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“域名和SEO需要注意什么”这篇文章吧。  一、优先考虑品牌  真正的好的域名都不会在域名中包含关键...
    99+
    2023-06-10
  • 打包 PHP 和 npm 项目时需要注意哪些问题?
    随着现代 Web 开发的不断发展,前后端分离的开发方式越来越普遍,这也意味着我们需要将前端代码和后端代码打包到一起。在这个过程中,我们需要注意哪些问题呢? 一、PHP 项目打包 PHP 项目打包的主要方式是将代码打包成 PHAR(PHP ...
    99+
    2023-07-30
    npm 并发 打包
  • 为什么Java打包需要注意缓存?学习笔记分享。
    Java作为一种强大的编程语言,被广泛应用于各种应用程序的开发。在使用Java进行开发过程中,我们经常需要将程序打包成可执行的JAR文件,以便于在不同的环境下进行部署和运行。但是,在进行Java打包时,我们需要特别注意缓存问题。本文将从缓存...
    99+
    2023-06-14
    打包 学习笔记 缓存
  • Kali Linux需要注意什么
    这期内容当中小编将会给大家带来有关Kali Linux需要注意什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Kali Linux 在渗透测试和白帽子方面是业界领先的 Linux 发行版。默认情况下,该...
    99+
    2023-06-28
  • 注册域名需要注意什么
    本篇内容介绍了“注册域名需要注意什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!第一,域名注册商的时候,要了解该注册的品牌。尽量挑选老练,...
    99+
    2023-06-06
  • ASP、Linux和NPM的打包过程中需要注意哪些问题?
    ASP、Linux和NPM是现代Web开发中常用的工具和技术。在开发过程中,打包是非常重要的一步,它能够将应用程序的所有组件和依赖项打包成一个可执行的文件或者库。然而,在打包过程中可能会出现一些问题,下面就让我们来一起探讨一下ASP、Lin...
    99+
    2023-06-25
    linux npm 打包
  • PHP 和 NPM 的函数打包,有哪些需要注意的事项?
    在 PHP 和 NPM 中,函数打包是一种非常常见的技术。它可以将多个函数打包到一个文件中,以便于组织和管理。但是,在进行函数打包时,需要注意以下几个事项,以避免出现意外的错误。 命名空间的问题 在 PHP 中,如果你将多个函数打包到...
    99+
    2023-09-12
    npm 函数 打包
  • Java路径打包有哪些需要注意的问题?
    Java作为一种常用的编程语言,经常需要进行打包操作。在进行Java路径打包时,需要注意一些问题,以确保打包后的程序能够正常运行。下面将介绍一些Java路径打包需要注意的问题。 打包时需要注意的文件 在进行Java路径打包时,需要注意哪...
    99+
    2023-08-22
    path 打包 索引
  • mysql建表需要注意什么
    本篇文章和大家了解一下mysql建表需要注意什么。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。一、mysql各个名称库名、表名、字段名全部使用小写字母,用'_'下划线分割...
    99+
    2024-04-02
  • Access转SqlServer需要注意什么
    本篇内容介绍了“Access转SqlServer需要注意什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2024-04-02
  • 使用View.post()需要注意什么
    这篇文章给大家分享的是有关使用View.post()需要注意什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、前言有时候,我们会需要用到 View.post() 方法,来将一...
    99+
    2024-04-02
  • seo建站需要注意什么
    seo建站时需要注意以下几个点网站布局网站的内容布局模式,一般采用扁平化的树形模式,将重要的文章和栏目布局到首页,通过首页点击栏目进入到列表页,有利于蜘蛛抓取页面。代码编写的格式seo建站一般采用DIV+CSS的模式来进行代码的编写,使网站...
    99+
    2024-04-02
  • 学习Linux需要注意什么
    小编给大家分享一下学习Linux需要注意什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、不要“玩 Linux”  很多人用 Linux 的时候会感觉很迷茫,...
    99+
    2023-06-13
  • 初学J2ME需要注意什么
    这篇文章主要讲解了“初学J2ME需要注意什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“初学J2ME需要注意什么”吧!  下面请看一段代码:    import javax.microed...
    99+
    2023-06-03
  • html5测试需要注意什么
    这篇文章主要介绍“html5测试需要注意什么”,在日常操作中,相信很多人在html5测试需要注意什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”html5测试需要注意什么”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作