I'm trying to compile my first application that uses PyQt. It compiles successfully, but if I try to run, it says:
WindowsError: [Error 2] : 'C:/Users/GHOSTM~1/AppData/Local/Temp/_MEI8722\\icons'
It says where is original error. It is in line where I set icons:
action = QtGui.QAction(QtGui.QIcon(':/data/%s' % icon), name, parent)
As you can see I import icon from resource module, which was generated with pyrcc4.exe from qrc file. Original qrc file contains such information:
<RCC>
<qresource>
<file>../data/dictionary.png</file>
<file>../data/perseus.png</file>
<file>../data/settings.png</file>
<file>../data/help.png</file>
<file>../data/quit.png</file>
</qresource>
</RCC>
Python module was generated successfully, original script works good. Am I doing smth wrong?
Related
I am trying to open a .dat file by Pickle. Although the file is at the same folder as my .py file, when I run I get a FileNotFoundError.
(FYI: I am using VScode to run the file, however, it runs perfectly fine when I use Terminal)
here is my code
import pickle
websites_list = pickle.load(open("websites.dat","rb"))
print(websites_list)
This is the .py path:
/Users/lequangdang/Documents/WSC/WSC_2.0/changewebsiteGUI.py
here is the .dat path: /Users/lequangdang/Documents/WSC/WSC_2.0/websites.dat
Here is the error:
FileNotFoundError: [Errno 2] No such file or directory: 'websites.dat'
The relative path is base on work directory when using vscode, but is base on py file itself when using terminal.
For example the directory structure seems like:
WSC---WSC2.0---changewebsiteGUI.py
when you open WSC in vscode, pickle.load(open("websites.dat","rb")) will call the path WSC/websites.dat and that's why you have FileNotFoundError
one way to solve this is to set the vscode launch.json, add this line:
"cwd": "${workspaceRoot}/WSC2.0"
the other way is to use some function to get the abs path of pyfile itself:
os.path.dirname(os.path.abspath(__file__))
I'm trying to export my .py script to .exe using PyInstaller, which has dependencies on .ui files which were created using Qt Designer.
I can confirm that my .py script works just fine when running it through PyCharm - I'm able to see the GUI I've created with the .ui files.
However, when I export my .py script to .exe and launch it, I recieve the following errors in the command line:
C:\Users\giranm>"C:\Users\giranm\PycharmProjects\PyQt Tutorial\dist\secSearch_demo.exe"
Traceback (most recent call last):
File "secSearch_demo.py", line 13, in <module>
File "site-packages\PyQt4\uic\__init__.py", line 208, in loadUiType
File "site-packages\PyQt4\uic\Compiler\compiler.py", line 140, in compileUi
File "site-packages\PyQt4\uic\uiparser.py", line 974, in parse
File "xml\etree\ElementTree.py", line 1186, in parse
File "xml\etree\ElementTree.py", line 587, in parse
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\giranm\\securitySearchForm.ui'
Failed to execute script secSearch_demo
For some reason, the .exe file is looking for the .ui file within the path - C:\Users\giranm\
However, having done some research already, I was told that I needed to use os.getcwd() and ensure that I have the full path in my script. Even with the code below, I still get errors trying to locate the .ui files.
PyInstaller: IOError: [Errno 2] No such file or directory:
# import relevant modules etc...
cwd = os.getcwd()
securitySearchForm = os.path.join(cwd, "securitySearchForm.ui")
popboxForm = os.path.join(cwd, "popbox.ui")
Ui_MainWindow, QtBaseClass = uic.loadUiType(securitySearchForm)
Ui_PopBox, QtSubClass = uic.loadUiType(popboxForm)
# remainder of code below.
I'm aware that one can convert .ui files to .py and import them into the main routine using pyuic4. However, I will be making multiple edits to the .ui files
and thus it is not feasible for me to keep converting them.
Is there anyway to fix this so that I can create a standalone .exe?
I'm fairly new to using PyQT4 and PyInstaller - any help would be much appreciated!
After scratching my head all weekend and looking further on SO, I managed to compile the standalone .exe as expected using the UI files.
Firstly, I defined the following function using this answer
Bundling data files with PyInstaller (--onefile)
# Define function to import external files when using PyInstaller.
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)
Next I imported the .UI files using this function and variables for the required classes.
# Import .ui forms for the GUI using function resource_path()
securitySearchForm = resource_path("securitySearchForm.ui")
popboxForm = resource_path("popbox.ui")
Ui_MainWindow, QtBaseClass = uic.loadUiType(securitySearchForm)
Ui_PopBox, QtSubClass = uic.loadUiType(popboxForm)
I then had to create a resource file (.qrc) using Qt Designer and embed images/icons using this resource file. Once done, I used pyrcc4 to convert the .qrc file to .py file, which would be imported in the main script.
Terminal
C:\Users\giranm\PycharmProjects\PyQt Tutorial>pyrcc4 -py3 resources.qrc -o resources_rc.py
Python
import resources_rc
Once I have confirmed the main .py script works, I then created a .spec file using PyInstaller.
Terminal
C:\Users\giranm\PycharmProjects\PyQt Tutorial>pyi-makespec --noconsole --onefile secSearch_demo.py
As per PyInstaller's guide, I've added data files by modifying the above .spec file.
https://pythonhosted.org/PyInstaller/spec-files.html#adding-data-files
Finally, I then compiled the .exe using the .spec file from above.
You can simply use:
uic.loadUi(r'E:\Development\Python\your_ui.ui', self)
Use the full path, and use pyinstaller with standard arguments, and it works fine. The r prefix makes sure the backslashes are interpreted literally.
Another method, tested on Ubuntu 20.04 is to add the .ui file to the data section in the spec file. First generate a spec file with pyinstaller --onefile hello.py. Then update the spec file and run pyinstaller hello.spec.
a = Analysis(['hello.py'],
...
datas=[('mainwindow.ui', '.')],
...
The next step is to update the current directory in your Python file. To do this, the os.chdir(sys._MEIPASS) command has to be used. Wrap it in a try-catch for development use when _MEIPASS is not set.
import os
import sys
# Needed for Wayland applications
os.environ["QT_QPA_PLATFORM"] = "xcb"
# Change the current dir to the temporary one created by PyInstaller
try:
os.chdir(sys._MEIPASS)
print(sys._MEIPASS)
except:
pass
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication
from PySide2.QtCore import QFile, QIODevice
if __name__ == "__main__":
app = QApplication(sys.argv)
ui_file_name = "mainwindow.ui"
ui_file = QFile(ui_file_name)
if not ui_file.open(QIODevice.ReadOnly):
print(f"Cannot open {ui_file_name}: {ui_file.errorString()}")
sys.exit(-1)
loader = QUiLoader()
window = loader.load(ui_file)
ui_file.close()
if not window:
print(loader.errorString())
sys.exit(-1)
window.show()
sys.exit(app.exec_())
hi i have the following code in my main.py file
store = JsonStore(r'save/budgets/{}'.format(budgetName))
store.put('budget', items= ['soap','drinks'], total=10)
Where "budgetName" is gotten from a textinput entry.
"save" is a folder in the same directory as my main.py,
and "budgets" is a folder found in the "save" directory,
the plan is to create the .json file in the budgets directory.
This used to work when i tested on kivy launcher on my android phone. But once i created an apk,
it crashes the program with the error exception
Errno 2: No such file or directory
please how do i fix this
I have seen Qt documentary and a lot of questions less-similar to this one, But i still haven't figured out how can i do it.
I'm not entirely sure how can i import resource file to Python code, so pixmap appears without any issues.
I have all files in same directory, I created qrc. file and compiled it with: rcc -binary resources.qrc -o res.rcc to make resource file.
I imported res_rcc but pixmap on label was still not shown:
import res_rcc
This is what i had in my qrc. file:
<RCC>
<qresource prefix="newPrefix">
<file>download.jpeg</file>
</qresource>
</RCC>
Question:
How can i import resource files in the PyQt code ? | If pixmaps are in same directory as .qrc resource files, Do i still need to specify full path?
For pyqt you have to use pyrcc4, which is the equivalent of rcc for python.
pyrcc4 -o resources.py resources.qrc
This generates the resources.py module that needs to be imported in the python code in order to make the resources available.
import resources
To use the resource in your code you have to use the ":/" prefix:
Example
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import resources
pixmap = QPixmap(":/newPrefix/download.jpeg")
See The PyQt4 Resource System and The Qt Resource System
In PyQt5, we should write in comand line
pyrcc5 -o resources.py resource/resources.qrc
Because, we need to generate a resource.py to import in the code. Now we can type
import resources
in our python code
In addition to the above wonderful answers, if you would also like the ability to set the icon from within QtCreator itself (instead of having to do the say setWindowIcon(QIcon('://images/app_icon.ico')) line in code), you do this:
pyrcc5 -o resources_rc.py resources.qrc
cd ui
pyuic5 -o dialog.py dialog.ui
(Note that pyuic5 automatically imports resources_rc and not resources for some reason; hence the new name specified above)
Where you've made sure that:
...
</tabstops>
<resources>
<include location="../resources.qrc"/>
</resources>
<connections>
...
appears approximately there (between tabstops and connections) in your dialog.ui file. I think to get it there automatically, you can create a dummy C++ project and add your .ui files to the dummy project, then add a new Qt Resource file to the project. When your done, you can delete everything leaving the .ui files and the .qrc file. If you happen to copy resources.qrc to another directory, then closing and re-opening the dialog.ui file will prompt you for where the new location is.
Now you can set the resources from the Property explorer on in QtCreator: windowIcon > Choose Resource > (click on the root) > (your files should show up now) > (select app_icon.ico).
I just checked a newly created mainwindow.ui, if you open up the file in Text Edit mode in Qt Creator it shows you where the <resource /> stub is. Simply insert there (using some other program) For some reason opening up the newly created .ui file in Notepad++ was not showing it.
When closing and re-opening files, you must actually close the file (not "Reload" - doesn't work) and open it again. Then the resource root in "add image from resources" dialog will be non-empty.
I have converted a python game I designed into an exe. Running the exe itself causes it to flash and then close, meaning an error has occured. Running it from the Command Prompt causes the error as well, but documents it:
Cannot load image: Playfield.png
Couldn't open images\Playfield.png
This is telling me that the load_image block is failing. I have encountered this before when I did not have an images directory.
I attempted to move the images folder to the dist directory. This is the error that shows up:
Traceback (most recent call last):
File "Table_Wars.py", line 728, in <module>
File "Table_Wars.py", line 51, in main
File "Table_Wars.py", line 236, in __init__
File "pygame\__init__.pyc", line 70, in __getattr__
NotImplementedError: font module not available
(ImportError: DLL load failed: The specified module could not be found.)
This is my first time with py2exe, so I'm not really sure what is happening. The raw python file itself, Table_Wars.py, runs as expected.
If it helps, the location for the entire Table_Wars folder is inside a folder called Games, located on my Desktop (C:\Users\Oventoaster\Desktop\Games\Table_Wars). I am running Windows 7 32 bit OS.
On request, here is the output.txt I have generated:
Folder PATH listing for volume OS
Volume serial number is 7659-4C9C
C:\USERS\OVENTOASTER\DESKTOP\GAMES\TABLE_WARS
build
bdist.win32
winexe
bundle-2.7
collect-2.7
ctypes
distutils
email
mime
encodings
logging
multiprocessing
dummy
pygame
threads
unittest
xml
parsers
temp
dist
images
Here is the setup.py I used to convert the file:
from distutils.core import setup
import py2exe
setup(console=['Table_Wars.py'])
EDIT: I have attempted to use the full py2exe example. This will create the exe, but gives the same Cannot load image error. Attempting to put the images folder in the same folder as the exe creates a Runtime Error: The application requested the runtime to terminate it in an unusual way.
The shortened form of the code Slace Diamond suggested prevents py2exe from finding Table_Wars.py:
from cmd:
running py2exe
*** searching for required modules ***
error: Table_Wars.py: No such file or directory.
setup and Table_Wars are in the same directory. If it help, I input the full path to python.exe and setup.py.
EDIT: I seem to be getting closer. I put the images directory within self.extra_datas, and now I am getting this:
Fatal Python error: (segmentation fault)
This application has requested the runtime to terminate it in an unusual way. Please contact the application's suppourt team for more information
When you build a distributable package with py2exe (and py2app for that matter), part of the package environment is to point to a local resource location for files. In your plain unpackaged version, you are referring to a relative "images/" location. For the packaged version, you need to configure your setup.py to include the resources in its own location.
Refer to this doc for very specific info about how to set the data_files option of your package: http://www.py2exe.org/index.cgi/data_files
That page has multiple examples to show both very simple paths, and also a helper function for finding the data and building the data_files list for you.
Here is an example of the simple snippet:
from distutils.core import setup
import py2exe
Mydata_files = [('images', ['c:/path/to/image/image.png'])]
setup(
console=['trypyglet.py.py']
data_files = Mydata_files
options={
"py2exe":{
"unbuffered": True,
"optimize": 2,
"excludes": ["email"]
}
}
)
This closely matches what you are trying to achieve. It is saying that the "image.png" source file should be placed into the "images" directory at the root of the resources location inside the package. This resource root will be your current directory from your python scripts, so you can continue to refer to it as a relative sub directory.
It looks like you've already fixed the image problem by moving the folder into dist. The missing font module, on the other hand, is a known problem between pygame and py2exe. Py2exe doesn't copy some necessary DLLs, so you have to override py2exe's isSystemDLL method, forcing it to include audio and font related DLLs.
If Table_Wars.py is the only module in your project, try running this script with python setup.py py2exe:
from os.path import basename
from distutils.core import setup
import py2exe
origIsSystemDLL = py2exe.build_exe.isSystemDLL
def isSystemDLL(pathname):
if basename(pathname).lower() in ("libogg-0.dll", "sdl_ttf.dll"):
return 0
return origIsSystemDLL(pathname)
py2exe.build_exe.isSystemDLL = isSystemDLL
setup(windows=[{"script": "Table_Wars.py"}],
options={"py2exe": {"dist_dir": "dist"}})
You could also try the example py2exe setup file on the pygame wiki. If neither of them are working, please add the error messages to your question.
I tried running py2exe on a sample project, and it also breaks for me when I use the default pygame font. If you're using the default font, try putting a ttf file in the root of your project and also in the dist folder. You'll have to change the call to pygame.Font in your script as well:
font = pygame.font.Font("SomeFont.ttf", 28)