How do I correctly package PySide6 using cxfreeze? - python

I have written a fairly simple GUI application using Python 3.8.0 and PySide6 and I would like to package it for distribution. Based on the table here, I chose cxfreeze as it's compatiable with Qt6 and with Windows/Linux/Mac.
My application in running with a pyenv environment on my development machine, if that makes a difference. The machine is running Debian Bullseye.
I ran the cxfreeze-quickstart wizard in order to create the setup.py script. The output from the script is here (apologies for pastebin link, the text is too long for stackoverflow)
When I run the created executable (build/build/exe.linux-x86_64-3.8/sne), I get the following error:
Traceback (most recent call last):
File "/home/james/.pyenv/versions/3.8.0/lib/python3.8/site-packages/cx_Freeze/initscripts/__startup__.py", line 104, in run
module_init.run(name + "__main__")
File "/home/james/.pyenv/versions/3.8.0/lib/python3.8/site-packages/cx_Freeze/initscripts/Console.py", line 15, in run
exec(code, module_main.__dict__)
File "app.py", line 7, in <module>
ImportError: libpyside6.abi3.so.6.1: cannot open shared object file: No such file or directory
The libpyside6.abi3.so.6.1 file is in the build/exe.linux-x86_64-3.8/lib/PySide6 directory.
I added a line to print the contents of sys.path when the application runs:
['/home/james/code/cave-escape/simple-nano-ethernet/SNEGui/build/exe.linux-x86_64-3.8/lib/library.zip', '/home/james/code/cave-escape/simple-nano-ethernet/SNEGui/build/exe.linux-x86_64-3.8/lib']
The lib/PySide6 directory is not in the path, but I believe this is not the issue as the PySide6 package is present in lib.
If I run ldd against libpyside6.abi3.so.6.1, all the dependencies have filepath listed against them except for one:
libshiboken6.abi3.so.6.1 => not found
This file is present in build/exe.linux-x86_64-3.8/lib/shiboken6 directory.
I am guessing I need to make a manual edit to the setup.py script to fix this, or perhaps edit the sys.path at application startup, but I'm not sure exactly what to do in either case.
EDIT: contents of setup.py (autogenerated, unaltered):
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need
# fine tuning.
build_options = {'packages': [], 'excludes': []}
import sys
base = 'Win32GUI' if sys.platform=='win32' else None
executables = [
Executable('app.py', base=base, target_name = 'sne')
]
setup(name='Simple Nano Ethernet GUI',
version = '1.0',
description = 'An interface to configure the simple nano ethernet board',
options = {'build_exe': build_options},
executables = executables)

Related

ImportError on python exe file

Using py2exe I create an exe version of my script with instructions I found here. The script compiles well and generates a dist and build folder each but when I run the program on the command line it gives this error. N.B the script works fine on my IDE environment, however I intend give a colleague the exe version.How can I fix this error?
Traceback (most recent call last):
File "tester2.py", line 4, in <module>
ImportError: No module named mechanize
here is the setup.py file:
from distutils.core import setup
import py2exe
setup(
console = ['tester2.py'],
zipfile = None,
)
You have to declare your dependencies.
This is my setup
setup(
executables=executables,
options=options,
name='bla',
version='0.3',
packages=[...],
url='',
license='',
author='',
author_email='',
description='', requires=['pandas', 'unidecode', 'click',
'xlsxwriter'] // you would have to add mechanize here
)
Have you added files to the build?
Pls have a look at include option in setup.py: exe built with cx_Freeze, PyQt5, Python3 can't import ExtensionLoader_PyQt5_QtWidgets.py and run
Also here's my solution to similar problem, how to add files to build and run them later: Python - create an EXE that runs code as written, not as it was when compiled

cxFreeze and Jaraco: ImportError

I'm trying to create an IRC client using the irclib library. When I try to freeze the script using cxFreeze, however, I always run into that error:
Traceback (most recent call last):
File "C:\python27\lib\site-packages\cx_Freeze\initscripts\Console.py", line 27, in <module>
exec(code, m.__dict__)
File "client.py", line 38, in <module>
ImportError: No module named jaraco
The setup.py script has been modified several times, to try to include files, packages and so on. Nothing seems to work. Here's the current version for reference:
from cx_Freeze import setup, Executable
client = Executable(
script="client.py",
base="Win32GUI",
)
setup(
name = "client",
version = "0.2",
description = "client",
options = {'build_exe': {'includes': ["jaraco"], "packages": ["jaraco"]}},
executables = [client],
)
The script of the client can be shortened in a single line:
from irc import client
That's all. I'm not using Jaraco, irclib (package irc) is. Jaraco must have been installed as a dependency from irclib.
I've tried to find the reasons why it could happen, but so far, nothing found.
Thanks for your help!
Well, after some digging around, it seems the same problem exists with zope when freezing an application with twisted. Although I haven't tested it with jaraco, I would imagine it's the same issue. I hope this solution works for users stuck with the same problem:
In your 'site-packages' directory, in the 'jaraco' package, add the 'init.py' file. It can be empty. Why isn't it provided, I have no idea. A package without a 'init.py", for cxFreeze, isn't a package.
Re-run the 'setup.py' script. Don't include 'jaraco' as a package, provide the package that needs it (here, it would be 'irc').
Here's the setup.py script:
from cx_Freeze import setup, Executable
client = Executable(
script="client.py",
base="Win32GUI",
)
setup(
name = "client",
version = "0.2",
description = "client",
options = {'build_exe': {'packages': ["irc"]}},
executables = [client],
)
I provide this answer because it worked just fine with twisted and zope. Seeing my client uses twisted now for its IRC communication, I don't know if the provided steps below work, but that's what helped me for twisted.
HTH,

Py2exe and selenium - IOError: [Errno 2] No such file or directory: '\\dist\\main.exe\\selenium\\webdriver\\firefox\\webdriver_prefs.json'

I wrote a simple application which uses selenium to nagivate through pages and download their source code. Now I would like to make my application Windows-executable.
My setup.py file:
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
setup(
options = {'py2exe': {'bundle_files': 1,
"dll_excludes": ['w9xpopen.exe', 'MSVCP90.dll', 'mswsock.dll', 'powrprof.dll', 'MPR.dll', 'MSVCR100.dll', 'mfc90.dll'],
'compressed': True,"includes":["selenium"],
}
},
windows = [{'script': "main.py", "icon_resources": [(1, "hacker.ico")]}],
zipfile = None
)
My program (main.py) (with setup.py file) is located in C:\Documents and Settings\student\Desktop. Py2exe builds my exe in C:\Documents and Settings\student\Desktop\dist.
I copied both webdriver.xpi and webdriver_prefs.json files to C:\Documents and Settings\student\Desktop\dist\selenium\webdriver\firefox\, but I'm getting the error when trying to launch my application:
Traceback (most recent call last):
File "main.py", line 73, in <module>
File "main.py", line 58, in check_file
File "main.py", line 25, in try_to_log_in
File "selenium\webdriver\firefox\webdriver.pyo", line 47, in __init__
File "selenium\webdriver\firefox\firefox_profile.pyo", line 63, in __init__
IOError: [Errno 2] No such file or directory: 'C:\\Documents and Settings\\student\\Desktop\\dist\\main.exe\\selenium\\webdriver\\firefox\\webdriver_prefs.json'
How to solve this?
Actually, it worked with such setup.py file:
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
wd_path = 'C:\\Python27\\Lib\\site-packages\\selenium\\webdriver'
required_data_files = [('selenium/webdriver/firefox',
['{}\\firefox\\webdriver.xpi'.format(wd_path), '{}\\firefox\\webdriver_prefs.json'.format(wd_path)])]
setup(
windows = [{'script': "main.py", "icon_resources": [(1, "hacker.ico")]}],
data_files = required_data_files,
options = {
"py2exe":{
"skip_archive": True,
}
}
)
But the problem is I need to build SINGLE executable.
Have you tried to have a look at this answer for the "bundle_files = 1" problems? It helped me solving that specific problem.
TL;DR --Please check out this tool I built: https://github.com/douglasmccormickjr/PyInstaller-Assistance-Tools--PAT
Might I suggest using PyInstaller instead of py2exe or anything else for that matter since PyInstaller does a far better job in terms of bundling a single executable. I'm on Windows about 90% of the time (no complaints here) with my python coding-- PyInstaller is a way better option than py2exe (for me at least -- I've used/test a great deal of Windows compilers in the past with varied success). Maybe other people suffering from compiling issues could benefit from this method as well.
PyInstaller Prerequisites:
Install PyInstaller from: http://www.pyinstaller.org/
After PyInstaller installation-- confirm both "pyi-makespec.exe" and "pyi-build.exe" are in the "C:\Python##\Scripts" directory on your machine
Download my PyInstaller-Assitance-Tools--PAT (it's just 2 batch files and 1 executable with the executable's source python file too -- for the paranoid)...The file are listed above:
Create_Single_Executable_with_NO_CONSOLE.bat
Create_Single_Executable_with_CONSOLE.bat
pyi-fixspec.exe
pyi-fixpec.py (optional -- this is the source file for the executable -- not needed)
Place the exectuable file called "pyi-fixspec.exe" inside the previous "Scripts" folder I mentioned above...this makes compiling much easier in the long run!
let's get it working now...some slight code changes to your python application
I use a standard function that references the location of applications/scripts that my python application needs to utilize to work while being executed/operated. This function operates both when the app is a standalone python script or when it's fully compiled via pyinstaller.
Here's the piece of code I use...
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
and here's my app using it....
source = resource_path("data\my_archive_file.zip")
that means the app/files look something like this in terms of directory structure:
C:\Path\To\Application\myscript_001.py <--- main application/script intended to be compiled
...
C:\Path\To\Application\data\my_archive_file.zip <---|
C:\Path\To\Application\data\images\my_picture.jpg <---| supporting files in the bundled app
C:\Path\To\Application\info\other_stuff.json <---|
...
Please note that the data/files/folders I'm bundling for my app are below the main executable/script that I'll be compiling...the "_MEIPASS" part in the function lets pyinstaller know that it's working as a compiled application...VERY IMPORTANT NOTE: Please use the function "resource_path" since the "pyi-fixspec.exe" application will be looking for that phrase/function while parsing/correcting the python application pathing
Goto the directory containing the 2 batch files mentioned above and type in either:
Option #1
C:\MyComputer\Downloads\PAT> Create_Single_Executable_with_NO_CONSOLE.bat C:\Path\to\the\python\file.py
The output executable file results in a GUI app when double clicked
Option #2
C:\MyComputer\Downloads\PAT> Create_Single_Executable_with_CONSOLE.bat C:\Path\to\the\python\file.py
The output executable file results in a WINDOWS CONSOLE app when double clicked -- expects commandline activity ONLY
Your new single-file-executable is done! Check for it in this location
C:\Original\Directory\ApplicationDistribution64bit\NameOfPythonFile\dist
If you do edit/change the original python file that has just been previously compiled, please delete the folder/contents of **\NameOfPythonFile** prior to next compile kickoff (you'll want to delete the historical/artifact files)
Coffee break -- or if you wany to edit/add ICONS to the executable (and other items too), please look at the generated ".spec" file and PyInstaller documentation for configuration details. You'll just need to kick off this again in the windows console:
pyi-build.exe C:\path\to\the\pythonfile.spec
You can build a single executable, which will run natively, by using Nuitka. It converts the Python code into C++ and then compiles it.
http://nuitka.net/
It does, however, require that you have a compiler installed. The appropriate versions of either Microsoft Visual C++ or GCC. Microsoft released "Microsoft Visual C++ Compiler for Python 2.7", which can be obtained here at https://www.microsoft.com/en-us/download/details.aspx?id=44266.
A nice installer of MinGW GCC for windows can be found at https://github.com/develersrl/gccwinbinaries with detailed instructions, including which MSVCRTXX.dll version to link with for which version of Python.
Things you will gain from this method of executable generation:
Doing this generates machine code, so it will be more difficult, but not impossible, to reverse engineer. Simply using Py2exe or PyInstaller, which are great for their intended use, only packages the byte compiled Python code, which is easily decompiled (http://www.simonroses.com/2013/10/appsec-myths-about-obfuscation-and-reversing-python/), into a zip appended executable.
Your application will also gain a bit of a speed boost. I wrote a blog post about this kind of thing at (I DO NOT receive money from click throughs or ads).
https://jaredfields83.wordpress.com/2015/12/21/squeezing-more-juice-from-python/.
The problem you have is that selenium is trying to open a file in a way that is not directly compatible with py2exe.
As you can see at line 63 here, selenium must open a preferences file that is usually shipped with the package. It uses the __file__ variable to find it, which doesn't play well with py2exe. As you have found, it is possible to work around that by also packaging up the prefs file in your distribution. However, that is now more than one file.
The py2exe wiki then has a recipe to use NSIS that will build a self-extracting executable of your complete distribution.

Py2exe compiles properly but the built application doesn't work

I am using Python 2.7 to build my application. Within it, I used few packages which are numpy, scipy, csv, sys, xlwt, time, wxpython and operator.
All the above packages are in 64-bit, and I am using python 2.7(64-bit version) in Aptana Studio 3(64-bit version) in Windows 7 Professional (64-bit version).
At last, I'd like to compile my project to an application using following code, the file name is py2exeTest.py:
from distutils.core import setup
import numpy # numpy is imported to deal with missing .dll file
import py2exe
setup(console=["Graphical_Interface.py"])
Then in cmd, I switched to the directory of the project and used following line to compile it:
python py2exeTest.py py2exe
Everything goes well, it generates an application under dist directory, and the application name is Graphical_Interface.exe.
I double clicked it, but there is a cmd window appears, and a python output windows flashes, then both of them disappeared. I tried to run the application as an administrator, the same outcome I've had.
May I know how to work this out?
Thanks!
EDIT:
I've managed to catch the error information that flashes on the screen. The error info I had is:
Traceback (most recent call last):
File "Graphical_Interface.py", line 397, in <module>
File "Graphical_Interface.py", line 136, in __init__
File "wx\_core.pyc", line 3369, in ConvertToBitmap
wx._core.PyAssertionError: C++ assertion "image.Ok()" failed at ..\..\src\msw\bitmap.cpp(802) in wxBitmap::CreateFromImage(): invalid image
I used one PNG image in the project, the code is like follows:
self.workflow = wx.Image("Work Flow.png", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
wx.StaticBitmap(self.panel_settings, -1, self.workflow, (330,270), (self.workflow.GetWidth(), self.workflow.GetHeight()))
I tried to comment the above chunk out from the project, and the application works properly. However, I need the image to show up in the application.
May I know how to deal with it?
Thanks.
Hiding console window of Python GUI app with py2exe
When compiling graphical applications you can not create them as a console application because reasons (honestly can't explain the specifics out of my head), but try this:
from distutils.core import setup
import numpy
import py2exe
import wxpython
setup(window=['Graphical_Interface.py'],
options={"py2exe" { 'boundle_files' : 1}})
Also consider changing to:
http://cx-freeze.sourceforge.net/
It works with Python3 and supports multiple platforms.
A cx_freeze script would look something like:
import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {"packages": ["os"], "excludes": ["tkinter"]}
# GUI applications require a different base on Windows (the default is for a
# console application).
base = None
if sys.platform == "win32":
base = "Win32GUI"
includefiles = ['/folder/image.png']
setup( name = "GUIprog",
version = "0.1",
description = "My GUI application!",
options = {"build_exe": build_exe_options, 'include_files' : includefiles},
executables = [Executable("Graphical_Interface.py", base=base)])
No worries, I've got the solution.
It turns out that the image is in the project folder rather than in the dist folder. So I have two solutions:
Copy the image into dist folder
Include the full path of the image in the code.
Thanks for your help.

Setting up PySide/Qt for GUI development

I have been trying to setup PySide/Qt for use with Python3.3. I have installed
PySide-1.2.0.win32-py3.3.exe
that I took from here and I have installed
qt-win-opensource-4.8.5-vs2010
that I took from here.
I generated .py files from .ui files (that I made using QtDesigner) using pyside-uic.exe as is explained in PySide Wiki.
Making .py files was working when I was using Qt5.1/QtCreator. I stopped using it when I found that I need to use Qt4.8 as explained on Qt-forums. With Qt4.8 it isn't working.
I want to develop GUI using PySide.
I want a drag-and-drop interface for making a skeleton GUI so I am using QtDesigner.
I am on Windows 7
I want to package the GUI developed into .exe files using cx-freeze.
My problem in short
What are the correct tools to use to make .ui with QtDesigner? How to convert them to .py files for use in Python using PySide?
cx_freeze is able to make my normal files to .exe Can it be used to convert the GUI made by Qt/PySide into .exe files? Would Qt be needed on other computers where the .exe of the GUI is distributed or would it be self-contained?
I used
cxfreeze testGUI.py --include-modules=PySide
to make the exe and related files. A directory dist was created with many files. On running nothing happened. So I used command line to find out the reason. The errors are
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\cx_Freeze\initscripts\Console3.py", line 27, in <module>
exec(code, m.__dict__)
File "testGUI.py", line 12, in <module>
File "C:\Python\32-bit\3.3\lib\importlib\_bootstrap.py", line 1558, in _find_and_load
File "C:\Python\32-bit\3.3\lib\importlib\_bootstrap.py", line 1525, in _find_and_load_unlocked
File "C:\Python33\lib\site-packages\PySide\__init__.py", line 55, in <module>
_setupQtDirectories()
File "C:\Python33\lib\site-packages\PySide\__init__.py", line 11, in _setupQtDirectories
pysideDir = _utils.get_pyside_dir()
File "C:\Python33\lib\site-packages\PySide\_utils.py", line 87, in get_pyside_dir
return _get_win32_case_sensitive_name(os.path.abspath(os.path.dirname(__file__)))
File "C:\Python33\lib\site-packages\PySide\_utils.py", line 83, in _get_win32_case_sensitive_name
path = _get_win32_long_name(_get_win32_short_name(s))
File "C:\Python33\lib\site-packages\PySide\_utils.py", line 58, in _get_win32_short_name
raise WinError()
FileNotFoundError: [WinError 3] The system cannot find the path specified.
Anyone knows what this stacktrace means?
There is a lot of win32 in here. But I have Windows 7 64-bit. I am using 32-bit Python and all modules were installed 32-bit. Could that cause a problem? I don't think it should as other exe I made for simple Python scripts were executing fine.
This error:
FileNotFoundError: [WinError 3] The system cannot find the path specified.
will be fixed in next pyside release (1.2.1). It will be released in next week.
btw: in case you don't want to generate custom bindings, you don't need to install qt, pyside installer contains all qt libraries and devel tools.
Regarded FileNotFoundError, I had a problem packaging a python 3 application with this for a few days. On a windows 7 64 bit machine it worked fine. When I built it on win7 32bit and tried to run the .exe file, I got all those file errors. After seeing this thread I checked the versions of pyside. On the win64 it was 1.1.2 on the win32 it was 1.2.0
I uninstalled pyside 1.2.0 on win32 and downloaded and installed the 1.1.2 win32 version. It now works ok.
This could be a stop gap measure until 1.2.1 is released.
I'm doing something similar (however I'm in the progress of migrating from PyQt to PySide).
You should use pyside-uic to generate the code for the GUI after creating the UI files in QtCreator (If this were PyQt "pyuic gui.ui > gui.py" would produce the desired code, I assume pyside-uic has a similar behaviour). I then subclass this generated code to customise the user interface.
Yes, you can use cx_freeze with PyQt/PySide, you'll want to include PySide in the "includes" item in the build options.
Yes, you can create a completely self-contained executable - you won't need Python, Qt or anything else.
Here's the build I use from my PySide GUI application.
__author__ = 'AlexM'
import sys
from cx_Freeze import setup, Executable
import MyPySideGui
import PySide, os
base = None
if sys.platform == "win32":
base = "Win32GUI"
QGifRelDir = "imageformats\qgif4.dll"
PySideDir = (os.path.join(os.path.dirname(PySide.__file__),"plugins"))
shortcut_table = [
("App Shortcut", # Shortcut
"ProgramMenuFolder", # Directory_
"MyPySideGUI", # Name
"TARGETDIR", # Component_
"[TARGETDIR]MyPySideApp.exe", # Target
None, # Arguments
None, # Description
None, # Hotkey
None, # Icon
None, # IconIndex
None, # ShowCmd
'TARGETDIR' # WkDir
)
]
build_exe_options = {
"include_files" : ["documentTemplate.html", "loading.gif", (os.path.join(PySideDir,QGifRelDir), QGifRelDir)],
"packages" : ["CustomHelperPackage", "AnotherCustomPackage", "MyPySideGui"],
"includes" : ["PySide"],
"excludes" : ["tkinter"],
'optimize': 2,
}
# Now create the table dictionary
msi_data = {"Shortcut": shortcut_table}
# Change some default MSI options and specify the use of the above defined tables
bdist_msi_options = {'data': msi_data}
executables = [ Executable("MyPySideGui.py", base = base) ]
setup(
name = "MyFirstPySideApplication",
version = str(MyPySideGui.version),
description = "MyPySideApp.exe Demonstrates PySide guis.",
options = {
"build_exe": build_exe_options,
"bdist_msi": bdist_msi_options
},
executables = executables
)
This example might be slightly complicated for you, but you can find simpler examples on the cx_freeze project homepage.
I'm not getting the issues you or the other answer are getting, but then I'm using Python 3.3.1 with PySide 1.1.2.
PySide 1.2.1 was released. It has fixed the error. I checked it by installing the new version and using cx_freeze.
No error in packaging with cx_freeze 4.3.1(32-bit version for Python 3.3) used with Python 3.3.2(32-bit) and PySide 1.2.1(32-bit) on Windows 7(64-Bit). I used the command written in the question to package it. It worked successfully.

Categories