Parent path Python Maya - python

I have a problem. I have a GUI in maya generated by a script in python.
The GUI, when launched opens an image.To load the image I used the following line of code:
cmds.image( image='/home/s4915717/myName/artefacts/Images/UIheader02.png' )
As you can understand, if I move my script into another computer, I should manually change the path to correctly load the image.
Is there a way to prevent this and let the program find to allocation of the image by itself?
I also tried to use the following method:
import os
.
.
.
path = os.path.abspath('myName/artefacts/Images/UIheader02.png')
cmds.image( image=path )
it works on my pc, but if I move on another one it doesn't work(yes I moved the whole folder with the image inside myName/artefacts...

Your first path is absolute, your second is relative, which may be part of your issue.
Depending on your OS, Maya looks in slightly different places in the user directory for icons. See this page in the docs down near the bottom, under XBMLANGPATH for the locations Maya is expecting. You can also set XBMLANGPATH to a custom location before starting Maya if you want to point at a special place, like a network share.

If your script is called from a file outside of Maya, you can use the __file__ attribute which will give you the path to the file where you use it. You can then use it to build your path.
For example, if your script is stored in '/home/s4915717/myName/artefacts', the __file__ will return '/home/s4915717/myName/artefacts'
So __file__ + '/Images/UIheader02.png' will give you the full path : '/home/s4915717/myName/artefacts/Images/UIheader02.png'
The safest way is probably to have all your scripts stored in a specific folder (for example the Maya script file) from which you can build relative paths.

Like Martin mentioned, you can use __file__ within your script and it will return that script's full path.
So let's say you have your image in a folder with your script like so:
+--my_script.py
+--my_folder
| +--my_image.png
You can access the image in your script this way:
import os
os.path.join(os.path.dirname(__file__), "my_folder", "my_image.png")
And let's say your folder was up one directory like so:
+--my_image.png
+--my_folder
| +--my_script.py
You can use os.path.abspath instead:
import os
os.path.abspath(os.path.join(__file__, "..", "..", "my_image.png"))
abspath helps resolve the ".." to go up a directory. At the end you can use os.path.exists to verify that the resulting path does in fact exist.

Related

correct path for np.load function in python

I have a small question which about the funcion of numpy load.
First I save a Matrix called matrix.npy to a Folder called No_Shadowing using np.save.
I have the following folder structure: scripts -> Plots -> NO_Shadowing
Inside the folder scripts I create a script in which I want to load the saved matrix.
I don't understand which path I should give np.load, so that it loads my file.
Do I need to give the path from scripts, e.g. something like np.load('Plots/No_Shadowing/matrix.np)? I tested all variants I can imagine, none worked.
Depends...if the path is relative to your current folder you can use:
import os
np.load(os.getcwd() + "\\scripts\\Plots\\No_Shadowing\\matrix.np")
or...if scripts is at the root dir.
np.load('c:\\scripts\\Plots\\No_Shadowing\\matrix.np')

Path.resolve() is losing relative information in Python

The following code using Path() is losing relative information:
src_file=inspect.getfile(CompileTypeData)
logger.debug(f'SRC_FILE: {src_file}')
src_path = Path(src_file).resolve()
logger.debug(f'SRC_PATH: {src_path}')
logger.debug(f'SRC_DIRNAME: {src_path.parent}')
Produces this:
DEBUG:from_project_types_file:SRC_FILE: ../../build_compile_mod/compile_type.py
DEBUG:from_project_types_file:SRC_PATH: /build_compile_mod/compile_type.py
DEBUG:from_project_types_file:SRC_DIRNAME: /build_compile_mod
What happened to my relative paths? It's my understanding that resolve() should make this an absolute path rather than losing data.
my_path.resolve() accepts an additional parameter, strict that defaults to False. If set to True, it raises a FileNotFoundError if the path cannot be resolved to an absolute path. That could be used to assess whether pathlib has enough data to create an absolute path from the string you obtained with inspect.getfile().
inspect.getfile() does not always return an absolute path, but you can always convert that path using os.path.realpath(inspect.getfile(obj)), or using Path.relative_to(...) method in combination with os.path.realpath(__file__).
Example of Relative Paths and sys.path.insert
If you put relative paths in to sys.path using
sys.path.insert and change directories while
running the script, then you'll get wrong answers
trying to use __file__ or anything derived from
it.
Say we have this:
/tmp/test1
/tmp/test2
/tmp/test2/mymod.py
/tmp/rundir/rundir2
So we CD to `/tmp/test2/ and launch the script.
% cd /tmp/test2
Now we create this script in Test2 that defines
show_path() which finds the path to mymod.py
and prints it.
Notice that sys.path.insert uses a relative path
this is the problem.
import sys
sys.path.insert(0,'../test1')
from mymod import *
import inspect
from pathlib import Path
def show_path():
myClassFile=inspect.getfile(MyClass)
print(Path(myClassFile).resolve())
So now we run our script. It starts in /tmp/test2/
it then changes directory and runs show_path().
Notice that show_path() points to nowhere because
of the relative path.
import os
os.chdir('/tmp/rundir/rundir2')
show_path()
This gives the following incorrect output.
/private/tmp/rundir/test1/mymod.py

How do you play sounds when the python file is in a different directory as the sound file?

So I'm making a text-based game, and after completion, I want to compile the end product to a .exe format so it's fairly easy to share (I plan on using cx_freeze)
Now, I wanted to add some background music for the game, the code below works fine IF AND ONLY IF the python file is on the desktop and so is the "sound.wav" I'm looking for ways to execute the sound.wav in background whether it's on the same or different directory as the python file, thanks
import winsound
winsound.PlaySound('sound.wav', winsound.SND_FILENAME)
Use os package to generate absolute path to your music file to make sure it always works fine.
For exampe, if your project's structure is
root
src
your_python_file.py
assets
sound.wav
So you can generate the absolute path to the sound.wav by
import os
# __file__ means the path of the current python script
root_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
bg_path = os.path.join(root_dir, "assets", "sound.wav")
Lets say you have a sub-folder called foo and a second sub-folder called subfoo
If you want go into foo sub-folder use foo/sound.wav if you want to go in the second sub-folder subfoo use foo/subfoo/sound.wav.
If you want to go up a dictionary you can use ./. For example if your sound is located in foo and you script in subfoo it could be accessed with ./sound.wav to go up one by one file use ./ again.
Otherwise you can use an 'absolute' file path where you start from C: or the drive you wish to access. For example if your file filename was located in Desktop you could use:
C:/users/username/Desktop/foo/subfoo/sound.wav

Access files relative to imported python module

Preliminary:
I have Anaconda 3 on Windows 10, and a folder, folder_default, that I have put on the Python path. I'm not actually sure whether that's the right terminology, so to be clear: regardless to where my Python script is, if I have a line of code that says import myFile, that line of code will succeed if myFile.py is in folder_default.
My issue:
In folder_default, I have:
A subfolder called useful_files which contains a text file called useful_file_1.txt.
A python script called my_misc.py.
my_misc.py has a line similar to: np.loadtxt('useful_files/useful_file_1.txt'). This line does not work if I use import my_script in a python file in a location other than folder_default, since useful_files/useful_file_1.txt is not the folder path relative to the python file that imports my_misc.py. I don't want to start using global file paths if I can avoid it.
How can I access files using file paths relative to the imported python module, rather than relative to the python script that imports that module?
Please let me know if the question is unclear - I tried to write a fake, minimal version of the setup that's actually on my computer in the hopes that that would simplify things, but I can change it if that actually makes things more confusing.
Thanks.
You can get the path to current module using the getfile method of inspect module as inspect.getfile(inspect.currentframe()).
For example:
# File : my_misc.py
import os, inspect
module_dir_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # get path to the directory of current module
useful_file_path = os.path.join(module_dir_path,'useful_files','useful_file_1.txt')
# path stored in useful_file_path. do whatever you want!
np.loadtxt(useful_file_path)

Image assets won't load when using pytest

I'm developing a GUI with PySide and I create pixmap from images like this:
PHONE_IMAGE_PATH = "resources/images/phone.png"
self.phone_null = QtGui.QPixmap(GREY_DOT_PATH)
self.phone_null = self.phone_null.scaledToWidth(20)
This works perfectly when I run the program but when I test it with py.test this happens:
QPixmap::scaleWidth: Pixmap is a null pixmap
It says that the pixmap is null, so it seems like the image wasn't loaded properly.
I really want to test my code and I can't find any information about this problem anywhere. Does anyone have a solution to my problem?
From Wikipedia:
By contrast, a relative path starts from some given working directory, avoiding the need to provide the full absolute path. A filename can be considered as a relative path based at the current working directory. If the working directory is not the file's parent directory, a file not found error will result if the file is addressed by its name.
It seems that ou are using a relative path for your image asset, so when you run your program the relative path is correct, but i assume that your tests are located in different directory from your main program.
You could obtain current file location with: __file__
Example:
main_script_dir = os.path.dirname(__file__)
rel_path = "resources/images/phone.png"
PHONE_IMAGE_PATH = os.path.join(main_script_dir, rel_path)

Categories

Resources