0

when I try to create a onefile executable with pyinstaller all the button-icons are removed. I want to use relative paths so that the .exe also runs on other computers. I found some old postings but I did not get these to work.

Python-Code:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(QtWidgets.QMainWindow):

    def __init__(self, debugging=False):
        super().__init__()
        self.__setupUi()
        self.__retranslateUi()
        QtCore.QMetaObject.connectSlotsByName(self)
        self.show()

    def __setupUi(self):        
        self.setObjectName('MainWindow')
        self.resize(400, 100)
        
        self.centralwidget=QtWidgets.QWidget(self)
        self.centralwidget.setObjectName('centralwidget')
        self.verticalLayout=QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName('verticalLayout')
        self.pushButton=QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setText('')
        icon=QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap('Icons/test.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon)
        self.pushButton.setIconSize(QtCore.QSize(32, 32))
        self.pushButton.setObjectName('pushButton')
        self.verticalLayout.addWidget(self.pushButton)
        self.setCentralWidget(self.centralwidget)

    def __retranslateUi(self):
        _translate=QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate('MainWindow', 'MainWindow'))


if __name__=='__main__':
    app=QtWidgets.QApplication(sys.argv)
    uiObj=Ui_MainWindow()
    sys.exit(app.exec())

PyInstaller-Command:

python -m PyInstaller --onefile --windowed --add-data Icons/*.png;Icons test.py

And the .spec content:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['test.py'],
             pathex=['C:\\Users\\User\\Desktop\\Neuer Ordner'],
             binaries=[],
             datas=[('Icons/*.png', 'Icons')],
             hiddenimports=[],
             hookspath=[],
             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='test',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False )

So how to fix this? Thx.

EGuy
  • 211
  • 1
  • 3
  • 10

1 Answers1

0

So today I found the solution. Really helpful was this old post (link). My folder structure is for example like:

Folder
    - test.py
    - absolutePath.py
    - Icons

The script absolutePath.py is needed to generate the absolute path of the PNGs. The folder Icons contains the PNG-Files.

absolutePath.py:

import sys
import os

def absolutePath(relative_path):
    base_path=getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__))) 
    return os.path.join(base_path, relative_path)

test.py:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from absolutePath import absolutePath


class Ui_MainWindow(QtWidgets.QMainWindow):

    def __init__(self, debugging=False):
        super().__init__()
        self.__setupUi()
        self.__retranslateUi()
        QtCore.QMetaObject.connectSlotsByName(self)
        self.show()

    def __setupUi(self):        
        self.setObjectName('MainWindow')
        self.resize(400, 100)
        
        self.centralwidget=QtWidgets.QWidget(self)
        self.centralwidget.setObjectName('centralwidget')
        self.verticalLayout=QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName('verticalLayout')
        self.pushButton=QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setText('')
        icon=QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(absolutePath('Icons/icon.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon)
        self.pushButton.setIconSize(QtCore.QSize(32, 32))
        self.pushButton.setObjectName('pushButton')
        self.verticalLayout.addWidget(self.pushButton)
        self.setCentralWidget(self.centralwidget)

    def __retranslateUi(self):
        _translate=QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate('MainWindow', 'MainWindow'))


if __name__=='__main__':
    app=QtWidgets.QApplication(sys.argv)
    uiObj=Ui_MainWindow()
    sys.exit(app.exec())

And finally the PyInstaller command:

python -m PyInstaller --onefile --windowed --add-data Icons\\*.png;Icons\\ test.py

The so generated executable includes all the PNGs from the folder Icons in a folder called Icons. The pictures can be found during runtime and appear. The executable can also be used on other computers.

EGuy
  • 211
  • 1
  • 3
  • 10