简体   繁体   中英

Icons in PyQt app created by Pyinstaller won't work on other computers

Ok, so I've written an application in pyqt and then prepared an exe file (one file) using pyinstaller. Everything works fine as long as the application is on my computer. But when I try to run it on other devices the icons in the app gui won't display. That leads me to a conclusion that pyinstaller is not including those icons in the exe file and is using them from a folder on my computer. How do I fix this?

In my python code I include icons like this:

self.TraceCheckBox.setIcon(QtGui.QIcon('d:/path/to/icons/icon1.png'))

and like this:

icon.addPixmap(QtGui.QPixmap(_fromUtf8("d:/path/to/icons/icon2.png")), QtGui.QIcon.Disabled, QtGui.QIcon.On)

EDIT1: I am using this function:

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)

And now I am accessing icons like that:

self.TraceCheckBox.setIcon(QtGui.QIcon(resource_path('icon1.png')))

This is my spec file:

# -*- mode: python -*-
a = Analysis(['name.py'],
             pathex=['D:\\my\\path\\app'],
             hiddenimports=[],
             hookspath=None,
             runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='name.exe',
          debug=False,
          strip=None,
          upx=True,
          console=False , version='version.txt', icon='road.ico')

Now where should I put this line to make it work? :

a.datas += [('images/icon1.png', 'D:\\my\\path\\to\\icons\\icon1.png','DATA')]

EDIT2: Now this is my new spec file:

# -*- mode: python -*-
a = Analysis(['name.py'],
             pathex=['D:\\my\\path\\app'],
             hiddenimports=[],
             hookspath=None,
             runtime_hooks=None)
pyz = PYZ(a.pure)

a.datas += [('images/red_dot1.png', 'D:\\my\\path\\to\\icons\\icons\\red_dot1.png','DATA'),('images/green_dot1.png','D:\\my\\path\\to\\icons\\icons\\green_dot1.png','DATA'),('images/repeat.png','D:\\my\\path\\to\\icons\\icons\\repeat.png','DATA'),('images/calibrate.png','D:\\my\\path\\to\\icons\\icons\\calibrate.png','DATA'),('images/report.png','D:\\my\\path\\to\\icons\\icons\\report.png','DATA'),('images/close_connection.png','D:\\my\\path\\to\\icons\\icons\\close_connection.png','DATA'),('images/auto_open.png','D:\\my\\path\\to\\icons\\icons\\auto_open.png','DATA'),('images/open_connection.png','D:\\my\\path\\to\\icons\\icons\\open_connection.png','DATA'),('images/read.png','D:\\my\\path\\to\\icons\\icons\\read.png','DATA')],
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='name.exe',
          debug=False,
          strip=None,
          upx=True,
          console=False , version='version.txt', icon='road.ico')

And I get this error:

Traceback (most recent call last):
  File "C:\Python27\Scripts\pyinstaller-script.py", line 9, in <module>
load_entry_point('PyInstaller==2.1', 'console_scripts', 'pyinstaller')()
  File "C:\Python27\lib\site-packages\PyInstaller\main.py", line 88, in run
run_build(opts, spec_file, pyi_config)
  File "C:\Python27\lib\site-packages\PyInstaller\main.py", line 46, in run_build
PyInstaller.build.main(pyi_config, spec_file, **opts.__dict__)
  File "C:\Python27\lib\site-packages\PyInstaller\build.py", line 1924, in main
build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "C:\Python27\lib\site-packages\PyInstaller\build.py", line 1873, in build
execfile(spec)
  File "roadtrace8.5.spec", line 20, in <module>
console=False , version='version.txt', icon='road.ico')
  File "C:\Python27\lib\site-packages\PyInstaller\build.py", line 1170, in __init__
strip_binaries=self.strip, upx_binaries=self.upx,
  File "C:\Python27\lib\site-packages\PyInstaller\build.py", line 1008, in __init__
self.__postinit__()
  File "C:\Python27\lib\site-packages\PyInstaller\build.py", line 309, in __postinit__
self.assemble()
  File "C:\Python27\lib\site-packages\PyInstaller\build.py", line 1035, in assemble
toc = addSuffixToExtensions(self.toc)
  File "C:\Python27\lib\site-packages\PyInstaller\build.py", line 179, in addSuffixToExtensions
for inm, fnm, typ in toc:
ValueError: too many values to unpack

I believe you use --onefile? With onedir you can check if pyinstaller included those png, so I recommend you to try first with onedir. However, you can say to pyinstaller to get those icons by changing .spec file with:

dict_tree = Tree('path to the folder with icons', prefix = 'nameofthefolder')   
coll = COLLECT(exe,
           a.binaries,
           dict_tree,
           a.zipfiles,
           a.datas,
           strip=None,
           upx=True,
           name='manage')

So please provide .spec file. And of course you should try with relative paths so change that in your code, that is I believe the main problem in here. EDIT Try:

a = Analysis(['name.py'],
         pathex=['D:\\my\\path\\app'],
         hiddenimports=[],
         hookspath=None,
         runtime_hooks=None)
pyz = PYZ(a.pure)

a.datas += [('images/icon1.png', 'D:\\my\\path\\to\\icons\\icon1.png','DATA')]

exe = EXE(pyz,
      a.scripts,
      a.binaries,
      a.zipfiles,
      a.datas,
      name='name.exe',
      debug=False,
      strip=None,
      upx=True,
      console=False , version='version.txt', icon='road.ico')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM