Search code examples
pyqtpyqt5pyinstaller

Backgroung set in stylesheet is seen with script.py but not after converting it to script.exe with pyinstaller


The background is set in the script as follows:

stylesheet = """
QMainWindow {
border-image: url(image.png) 0 0 0 0 stretch stretch;
background-repeat: no-repeat;
background-position: center;
}
"""

and later in

if __name__ == "__main__":
    import sys
    app1 = QApplication(sys.argv)
    app1.setStyleSheet(stylesheet)  # <---
    window = EncryptPDF()
    window.show()
    sys.exit(app1.exec_())

It works ok while used in the python script, but after converting to an executable with pyinstaller, the background image is not shown.
Any suggestions on how to fix it?
Thanks.


Solution

  • I've had this same problem before as well.

    In PyQt5 when setting that css using url(), the code is looking for your image.png the directory you give it, if there is no path then it looks in the same directory as the python script. When the python script is converted to an .exe that directory changes.

    What I do for my scripts is: I decide if the code is running as an exe or a python script by checking if sys has an attribute called "frozen" which is present when pyinstaller converts it to an .exe. If I know it's an exe, I then instead switch my base path to the path of my executable file, which should be put in the same place as your main python file in the directory.

    if getattr(sys, 'frozen', False):
        application_path = os.path.dirname(sys.executable)
        EXE_APPLICATION = True
    elif __file__:
        application_path = os.path.dirname(__file__)
        EXE_APPLICATION = False
    

    The code above is something I include in any python script I intend to convert to an exe. Throughout my project I will reference other files using something like:

    image_path = os.path.join(application_path, "image.png")
    
    stylesheet = """
    QMainWindow {
    border-image: url(image_path) 0 0 0 0 stretch stretch;
    background-repeat: no-repeat;
    background-position: center;
    }
    """
    

    EDIT:

    If your project includes multiprocessing don't forget to include

    from multiprocessing import freeze_support
    multiprocessing.freeze_support()
    

    This will make sure the multiprocessing works as an .exe.