Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add static(html, css, js, etc) files in pyinstaller to create standalone exe file?

I'm using QtWebEngineWidgets, QtWebChannel to create PyQt5 application, which uses HTML, CSS, JavaScript.

It's working fine, when we run in general way i.e., python main.py

Importing HTML as below,

current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "index.html")
url = QtCore.QUrl.fromLocalFile(filename)

Importing CSS, JavaScript files as below,

# in index.html
<link rel="stylesheet" href="styles.css">
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="my_custom.js"></script>

Now, I'm trying to create a standalone .exe file using pyinstaller.

I have tried from here with no success.

def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    try:
        # PyInstaller creates a temp folder and stores path in _MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

Pyinstaller command:

pyinstaller --onefile --windowed main.py

I need to manually add static files at generated .exe file to work as expected. Which I want to include it in .exe file itself. How to get this?

like image 229
Python coder Avatar asked Jan 29 '20 11:01

Python coder


1 Answers

From your question you can presume that the structure of your project is as follows:

├── index.html
├── jquery.js
├── main.py
├── my_custom.js
└── styles.css

For your case there are 2 options:

  1. using --add-data

    import os
    import sys
    
    from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
    
    
    def resource_path(relative_path):
        """ Get absolute path to resource, works for dev and for PyInstaller """
        try:
            # PyInstaller creates a temp folder and stores path in _MEIPASS
            base_path = sys._MEIPASS
        except Exception:
            base_path = os.path.abspath(".")
    
        return os.path.join(base_path, relative_path)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        view = QtWebEngineWidgets.QWebEngineView()
    
        filename = resource_path("index.html")
        url = QtCore.QUrl.fromLocalFile(filename)
    
        view.load(url)
        view.show()
        sys.exit(app.exec_())
    

    If you want to add external resources to the executable then you must use the "--add-data" option:

    pyinstaller --onefile --windowed --add-data="index.html:." --add-data="jquery.js:." --add-data="my_custom.js:." --add-data="styles.css:." main.py
    

    For windows change ":" with ";".

  2. using .qrc

    With this method you will convert the files (.html, .css, .js, etc) into .py code using pyrcc5 for this you must follow the following steps:

    2.1. Create a file called resource.qrc with the following content in the project folder:

    <RCC>
        <qresource prefix="/">
            <file>index.html</file>
            <file>jquery.js</file>
            <file>my_custom.js</file>
            <file>styles.css</file>
        </qresource>
    </RCC>
    

    2.2 Convert it to .py using pyrcc5:

    pyrcc5 resource.qrc -o resource_rc.py
    

    2.3 Import the resource_rc.py file and use the url with schema "qrc" in the main.py file:

    import os
    import sys
    
    from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
    
    import resource_rc
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        view = QtWebEngineWidgets.QWebEngineView()
    
        url = QtCore.QUrl("qrc:/index.html")
    
        view.load(url)
        view.show()
        sys.exit(app.exec_())
    

    2.4 Compile the project using your initial command

    pyinstaller --onefile --windowed main.py
    
like image 131
eyllanesc Avatar answered Oct 23 '22 19:10

eyllanesc