I used PyQT5 to develop a software using python.
now i have main.ui and main.py
i've used this command line to read main.ui file:
FORM_CLASS,_=loadUiType(path.join(path.dirname(__file__),"main.ui"))
now my main.ui is connected to my main.py file where main python code is written.
I also created setup.py as per cx_freeze instruction
Then I've used cmd command:
python setup.py build_exe
once completed i have received below error:
No such file or directory:'main.ui'
so ho i can solve this issue?
If you are going to use external resources then you should use the cx_freeze manual for data files:
Using data files Applications often need data files besides the code,
such as icons. Using a setup script, you can list data files or
directories in the include_files option to build_exe. They’ll be
copied to the build directory alongside the executable. Then to find
them, use code like this:
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
An alternative is to embed data in code, for example by using Qt’s
resource system.
So in your case modify your code to:
import os.path
import sys
# ...
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
# ...
FORM_CLASS,_=loadUiType(find_data_file("main.ui"))
# ...
And change the setup.py to include the .ui:
from cx_Freeze import setup, Executable
setup(
name="mytest",
version="0.1",
description="",
options={"build_exe": {"include_files": "main.ui"}},
executables=[Executable("main.py")],
)
Related
I am having issues with a converted .exe file. It does not find my excel file.
I have the following code
import pandas as pd
import os
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)
#Load data
data = pd.read_excel("data.xlsx")
...
The second part of the code (abspath, dname, os.chdir(dname) is setting the path to the location of the .py file. Hence, having the .py file and .xlsx file together will always make it find it no matter the location.
Then I convert it to .exe using
pyinstaller --hidden-import=pandas --onefile script.py
To make my script.py work, I have to have the data.xlsx file in the same folder as the script.py file.
I would assume dragging the .exe file out of the dir folder into the same location at as the .xlsx file would make it run but running the .exe files returns the following error:
Failed to execute script script. No such file 'data.xlsx' in directory.
How can I make it read my excel file no matter the location of the '.exe+.xlsx' folder?
The problem you're encountering is that when you run the executable the files are extracted to a temporary directory and run from there. This means that i) the current/working directory is the temporary directory and ii) the location of the program that is actually executing is also that temporary directory, so neither way of obtaining the path will do what you want.
However, when run as an executable some additional values are available via the sys module. The ones that are useful in this case are sys.frozen, which is set to True, and sys.executable, which is set to the location of the executable that the user ran.
In the past I've found the path I need in the following way:
if getattr(sys, 'frozen', False):
app_path = os.path.dirname(sys.executable)
else:
app_path = os.path.dirname(os.path.abspath(__file__))
where app_path will now be the directory of the script or executable. You can then use this as the basis of accessing other files.
for example if I
pip install ffmpeg-python
and run
os.system('ffmpeg -version')
it will print ffmpeg's version.
but if I save this line to main.py and pyinstaller --onefile main.py and run it, Windows can't find ffmpeg.
How do I tell pyinstaller to use the ffmpeg.exe thats in the Scripts folder?
Edit: I figured it out, answered below
I had a similar problem. I solved it by defining full path of local directory. After that I added this path to my EXE files in the current directory and run them. So try this:
from os import path
this_script_dir = path.dirname(path.realpath(__file__))
ffmpeg_path = this_script_dir + '\\ffmpeg.exe'
Ok this is how i did it:
#test.py
import sys
import os
if getattr(sys, 'frozen', False):
basedir = sys._MEIPASS
else:
basedir = os.path.dirname(os.path.abspath(file))
basedir = str(basedir)
os.system(basedir+'/ffmpeg.exe -version')
#works without the .exe also
and for pyinstaller you write
pyinstaller test.py --add-data "ffmpeg.exe;." --onefile
ffmpeg.exe is in the same folder as the test.py
How do I make a executable compiled with pyinstaller find its own name? I need this to make it copy itself to startup. Or is there another way to achieve this?
file only finds the original name of the script, not the executable.
Hope this solves your problem
import os
import sys
# uncompiled file.py can be found by
file_name = os.path.basename(__file__)
# compiled file.exe can find itself by
file_name = os.path.basename(sys.executable)
# and path to py or exe
current_path = os.path.realpath(sys.executable)
current_path = os.path.realpath(__file__)
I'm building a program with Python 3.3, Pyside and lxml amongst others. cx_Freeze was working like a charm until I starting sorting my modules into subdirectories for neatness. cx_Freeze works but reports the modules as missing and the output .exe file fails to load, but there are no issues opening the program with the .py file.
My folder structure is simple and only has 2 sub-folders called parsers and constants.
The cx_Freeze documentation allows for adding a path variable, but this doesn't search for the modules. All help appreciated.
import sys
from cx_Freeze import setup,Executable
includefiles = ['open.png', 'appicon.png']
includes = []
excludes = ['Tkinter']
packages = ['lxml._elementpath','lxml.etree']
build_exe_options = {'excludes':excludes,'packages':packages,'include_files':includefiles}
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup(
name = 'Config-Sheets',
version = '0.1',
description = 'Convert system configuration into .XLSX files',
author = 'ZZZ',
author_email = 'XXX#YYY.com',
options = {'build_exe': build_exe_options },
executables = [Executable('main.py', base=base)]
)
Results in and an exe that can't run.
Missing modules:
...
? parsers.parsercelerra imported from main__main__
? parsers.parserVPLEX imported from main__main__
? parsers.parserrain imported from main__main__
You should be able to include your packages very simply:
packages = ['lxml._elementpath','lxml.etree', 'parsers', 'constants']
Of course the directories must contain __init__.py in order to be considered packages.
If this doesn't achieve the desired effect then it would be useful to see the import mechanism used in main.py to pull these files in. If it's doing anything other than a straightforward import (or from x import) this can give cx_Freeze problems finding it.
You should include your .py files in the setup.py script. If the file is not a part of Python itself, cx_freeze needs to know that you want those files included. You should add your extra .py files with their paths to the includefiles list. For instance:
import sys
from cx_Freeze import setup,Executable
includefiles = ['open.png', 'appicon.png', 'parsers\xtra_file1.py','constants\xtra_file2.py']
includes = []
excludes = ['Tkinter']
packages = ['lxml._elementpath','lxml.etree']
build_exe_options = {'excludes':excludes,'packages':packages,'include_files':includefiles}
...
Hope this helped.
I have a python script which contains:
tempBook = temp.Workbooks.Open("c:\users\CNAME\desktop\Template.xlsx")
Everything works fine but when I create a .exe of my script the Template.xlsx is not included in its 'build' folder, it needs Template.xlsx to be present on the desktop. I want to make a portable exe.
Is there any way so that it can be included in the build, and make a standalone exe without any dependencies?
You need to move the file to your package, and list it in your setup.py:
setup(
# ...
data_files = [('', ['Tempate.xlsx',])],
)
See the data_files documentation for py2exe, which includes a utility function for automating adding data files.
The files will be added in your app root. From your main script, you can determine your app root by using:
import os
try:
approot = os.path.dirname(os.path.abspath(__file__))
except NameError: # We are the main py2exe script, not a module
import sys
approot = os.path.dirname(os.path.abspath(sys.argv[0]))