最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Please how do I compile a wxpython app that runs a flask server? - Stack Overflow

programmeradmin0浏览0评论

The wxpython application does not work as it is supposed to work after compiling it with pyinstaller. When I run the python code with the python interpreter, it works properly. But when it is bundled into an app.exe, web.html2 does not render the flask web pages properly. Here is the code:

# webview_app.py

import wx
import wx.html2
import threading
from flask import Flask, render_template


app = Flask(__name__)


@app.route('/')
def home():
    return """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bible Display Software</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: green;
        }
        .card {
            background-color: yellow;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
            text-align: center;
        }
        h1 {
            margin: 0;
        }
    </style>
</head>
<body>
    <div class="card">
        <h1>Bible Display Software</h1>
    </div>
</body>
</html>

"""


class MainFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='WxPython Flask App', size=(800, 600))
        
        panel = wx.Panel(self)
        self.browser = wx.html2.WebView.New(panel)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.browser, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        self.browser.LoadURL("http://127.0.0.1:5000")


def run_flask():
    app.run(host='127.0.0.1', port=5000)


def run_wx():
    wx_app = wx.App()
    frame = MainFrame()
    frame.Show()
    wx_app.MainLoop()


if __name__ == '__main__':
    flask_thread = threading.Thread(target=run_flask, daemon=True)
    flask_thread.start()  
    run_wx()

And below is the webview_app.spec file I tried.


#webview_app.spec
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

# Add the templates directory to the datas
added_files = [
    ('templates', 'templates'),  # (source_dir, dest_dir)
]

a = Analysis(
    ['webview_app.py'],
    pathex=[],
    binaries=[],
    datas=added_files,  # Include templates directory
    hiddenimports=['wx', 'wx.html2', 'wx._core', 'wx._html2', 'flask', 'werkzeug', 'jinja2'],
    hookspath=[],
    hooksconfig={},
    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,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='WebViewApp',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    windowed=True
)

The wxpython application does not work as it is supposed to work after compiling it with pyinstaller. When I run the python code with the python interpreter, it works properly. But when it is bundled into an app.exe, web.html2 does not render the flask web pages properly. Here is the code:

# webview_app.py

import wx
import wx.html2
import threading
from flask import Flask, render_template


app = Flask(__name__)


@app.route('/')
def home():
    return """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bible Display Software</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: green;
        }
        .card {
            background-color: yellow;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
            text-align: center;
        }
        h1 {
            margin: 0;
        }
    </style>
</head>
<body>
    <div class="card">
        <h1>Bible Display Software</h1>
    </div>
</body>
</html>

"""


class MainFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='WxPython Flask App', size=(800, 600))
        
        panel = wx.Panel(self)
        self.browser = wx.html2.WebView.New(panel)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.browser, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        self.browser.LoadURL("http://127.0.0.1:5000")


def run_flask():
    app.run(host='127.0.0.1', port=5000)


def run_wx():
    wx_app = wx.App()
    frame = MainFrame()
    frame.Show()
    wx_app.MainLoop()


if __name__ == '__main__':
    flask_thread = threading.Thread(target=run_flask, daemon=True)
    flask_thread.start()  
    run_wx()

And below is the webview_app.spec file I tried.


#webview_app.spec
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

# Add the templates directory to the datas
added_files = [
    ('templates', 'templates'),  # (source_dir, dest_dir)
]

a = Analysis(
    ['webview_app.py'],
    pathex=[],
    binaries=[],
    datas=added_files,  # Include templates directory
    hiddenimports=['wx', 'wx.html2', 'wx._core', 'wx._html2', 'flask', 'werkzeug', 'jinja2'],
    hookspath=[],
    hooksconfig={},
    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,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='WebViewApp',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    windowed=True
)
Share Improve this question asked Feb 2 at 11:44 Oluwatosin DurodolaOluwatosin Durodola 134 bronze badges 4
  • Is there any error ? – Maurice Meyer Commented Feb 2 at 12:15
  • No, It doesn't show any error message. It is just that the application does not display the full web page. But if I try example URL, it works. – Oluwatosin Durodola Commented Feb 2 at 12:57
  • From what I have seen this answer, I think the problem might be due to the threading, but I don't know the solution. stackoverflow/questions/78069910/… – Oluwatosin Durodola Commented Feb 2 at 15:53
  • @OluwatosinDurodola Check the response below, you can accept/upvote it if it solves your problem. – nepix32 Commented Feb 4 at 22:15
Add a comment  | 

1 Answer 1

Reset to default 0

Pyinstaller would create a working EXE out of the box (brand-new, Python 3.13.1/PyInstaller 6.11.1), but it looked weird. Found out EXE uses wx.html2.WebViewBackendIE and not wx.html2.WebViewBackendEdge. Reason for this is PyInstaller does not copy the interfacing DLL \Lib\site-packages\wx\WebView2Loader.dll

See this wxPython ticket for details

What I did to get a EXE where Edge is used as backend

rem change WINPYDIR to where your python is
rem set WINPYDIR="C:\Program Files\python"
pyinstaller ./app.py --distpath ./vdist -y --clean --contents-directory . --add-binary "%WINPYDIR%\Lib\site-packages\wx\WebView2Loader.dll:wx"

Alternatively, the following was proposed on the wxPython Forum

The absolute path can be avoided in the .spec file by:

  1. Add the following to the top of the .spec file
from PyInstaller import HOMEPATH
  1. Use the relative path as follows:
binaries=[(f’{HOMEPATH}/wx/WebView2Loader.dll’, ‘.’)],
发布评论

评论列表(0)

  1. 暂无评论