5

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?

1 Answer 1

8

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
    
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for helping. One small doubt,Using 2nd method: In HTML, do I need to import files as <script type="text/javascript" src="qrc:///jquery.js"></script>? or is there any other way?
Using first method, I got error pyinstaller: error: argument --add-data: invalid add_data_or_binary value: 'index.html:.'
@Pythoncoder try execute: pyinstaller --onefile --windowed --add-data="index.html;." --add-data="jquery.js;." --add-data="my_custom.js;." --add-data="styles.css;." main.py
Yes, it is working with ;. Thanks. What is the reason?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.