Bundle (Just --onefile)

给你一囗甜甜゛ 提交于 2020-01-24 14:27:08

问题


please read all this post and help me.

i want to create --onefile executable with pyinstaller.

i have these in Development side:

  • windows 8.1 x64
  • Qt 5.2.1
  • Python 27
  • PyQt5.2.1 (that built with Visual Studio 2012)
  • Visual Studio 2012
  • PyInstaller 2.1
  • pyWin32

and these in Deployment side (VirtualBox) (as a clean VM):

  • windows 8 x64
  • vcredist_x64 2012

and this is my simple python program that i want to build:

#main.py
import sys
from PyQt5.QtWidgets import QApplication, QPushButton

app = QApplication(sys.argv)

win = QPushButton("Hello World!")
win.show()

sys.exit(app.exec_())
#------------------------------------------------

ok, when i build it as --onedir (pyinstaller main.py) it works fine on development side and deployment side.

when i build it as --onefile (pyinstaller -F main.py) it works fine on development side but it does not work on deployment side.

and give this error:

This application failed to start because it could not find or load the Qt platform plugin "windows".

Available platform plugins are: minimal, offscreen, windows.

Reinstalling the application may fix this problem.

what is my fault?or what is the problem of this building?

in terms of this error it can not find qt5_plugins folder that is in _MEIxxxxx folder in temp folder.

or,do you think problem is from sys module?if yes, what should i do?

thanks for reply in advance

Update:

i should say that i have this warnnings and erro in build-time:

1024 WARNING: No such file C:\Python27\msvcp90.dll 1024 WARNING: Assembly incomplete 1026 ERROR: Assembly amd64_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_none not found

update2:

i added msvcp90.dll, msvcm90.dll to c:\Python27 manually, and this warnings and error is solved.

Update 3:

qt.conf:

[Paths]
Plugins = qt5_plugins

main.spec:

# -*- mode: python -*-
a = Analysis(['main.py'],
             pathex=['D:\\hello2'],
             hiddenimports=['sip', "PyQt5.QtCore", "PyQt5.QtGui", "PyQt5.QtWidgets"],
             hookspath=None,
             runtime_hooks=None)
pyz = PYZ(a.pure)
plugins = [("qt5_plugins/platforms/qwindows.dll",
             "C:\\Qt\\Qt5.2.1\\5.2.1\\msvc2012_64\\plugins\\platforms\\qwindows.dll", "BINARY")]
data = [
  ("qt.conf", "qt.conf", "DATA")
]
exe = EXE(
    pyz,
    a.scripts,
    a.binaries + plugins,
    a.zipfiles,
    a.datas + data,
    name='main.exe',
    debug=False,
    strip=None,
    upx=True,
    console=True
)

qt5_plugins that created automatically with pyinstaller have platform plugin.and i don't think it needs to add manually as extralib.


回答1:


I have just tried using pyinstaller for the first time and received the missing 'windows' message.

After looking at many 'solutions' and trying all kinds of things I finally solved by putting the qwindows.dll from C:\Python34\Lib\site-packages\PyQt4\plugins\platforms to the application directory (dist) plus qt4_plugins\platforms (I manually created the platforms directory, pyinstaller created the qt4_plugins directory)

Not as elegant as creating a qt.conf file, but it got the application working.

I should add I am using Windows 7, python 3.4 and PyQt4.




回答2:


Could this be a possible duplicate of someone elses attempts to build on OSX?

Anytime I used pyinstaller for PyQt4 building on Linux, I was never able to just build directly with the pyinstaller command and flags using the source python file. I had to first generate the spec file, and make modifications to it, and then build using that modified spec file.

It seems that you are not picking up the needed windows system files, along with the plugin files, as part of your build process. These would need to be manually added to your spec file to tell them to be collected as extra libs, along with a modified qt.conf file that sets the plugins location to be a relative one ([Paths]\nPlugins = qt5_plugins")

I don't have windows handy to show you a specific spec file, but here is something close as an example on my mac:

a = Analysis(
    ['/path/to/my/script.py'],
    # Path to extra pythonpath locations
    pathex=['/path/to/my/script'],
    # Extra imports that might not have been auto-detected
    hiddenimports=["PySide", "PySide.QtCore", "PySide.QtGui"],
    hookspath=None,
    runtime_hooks=None
)

pyz = PYZ(a.pure)

# Binary files you need to include in the form of:
# (<destination>, <source>, "<TYPE>")
plugins = [
  (
    "qt4_plugins/imageformats/libqjpeg.dylib", 
    "/usr/local/Cellar/qt/4.8.1/plugins/imageformats/libqjpeg.dylib", 
    "BINARY"
  ),
  (
    "qt4_plugins/phonon_backend/libphonon_qt7.dylib", 
    "/usr/local/Cellar/qt/4.8.1/plugins/phonon_backend/libphonon_qt7.dylib", 
    "BINARY"
  )
]

# Data files you want to include, in the form of:
# (<destination>, <source>, "<TYPE>")
data = [
  ("qt.conf", "qt.conf", "DATA")
]

exe = EXE(
    pyz,
    a.scripts,
    a.binaries + plugins,
    a.zipfiles,
    a.datas + data,
    name='script',
    debug=False,
    strip=None,
    upx=True,
    console=False, 
    resources=['qt.conf']
)

# This BUNDLE part is only relevant on a MAC
app = BUNDLE(
    exe,
    name='script',
    icon=None
)

I first use the utils/makespec.py to generate a "skeleton" spec file that has some initial options from the flags, and then modify it. Then I use pyinstaller on the spec file.

You can also look here for some other references, although it is still OSX: https://github.com/hvdwolf/pyExifToolGUI/blob/master/MacOSX/pyexiftoolgui.spec




回答3:


I could find the answer and complete work: there was some mistake that cause problem in running exe in clean vm:

  • using if __name__ == "__main__":
  • add our directory to PATH environment variable
  • add our folders or files that we need manually

    for example :

    • our .qml files or folder of images
    • qml directory for using qml files and etc

this is sample :

main.py

import sys
import os

from PyQt5.QtWidgets import QApplication, QPushButton
# from PyQt4.QtGui import QPushButton, QApplication

if getattr(sys, 'frozen', False):
    FullDirectory = os.path.join(os.environ.get("_MEIPASS", sys._MEIPASS))
    os.environ['PATH'] = FullDirectory
    # QApplication.addLibraryPath(FullDirectory)
else:
    FullDirectory = os.path.dirname(os.path.abspath(__file__))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = QPushButton("Hello World!")
    win.show()
    sys.exit(app.exec_())

and this is sample spec file:

main.spec

# -*- mode: python -*-
import os
import platform
import sys
sys.path.append("")

a = Analysis(['main.py'])
pyz = PYZ(a.pure)
exename = 'main.exe'
if "64" in platform.architecture()[0]:
    exename = 'main_x64.exe'

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    name=os.path.join('dist', exename),
    debug=False,
    strip=None,
    upx=True,
    console=True
)

i hope this be helpfull for you.

thanks to all




回答4:


The application failed to start because ... platform plugin "windows" error might also be due to UPX compression.

If you're using PyInstaller and have UPX set up for building then you'll have to manually replace the compressed qwindows.dll with the uncompressed one.

The uncompressed version can be found here:

C:\Python34\Lib\site-packages\PyQt5\plugins\platforms\qwindows.dll

Paste the above file in the temp PyInstaller folder which can be found somewhere like:

C:\Users\JohnSmith\AppData\Roaming\pyinstaller\bincache01_py34_64bit\qt5_plugins\platforms\

Then rerun your PyInstaller command



来源:https://stackoverflow.com/questions/23446124/bundle-just-onefile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!