I would like to write a script that can change the directory, have the user browse for a file and then read the data from the file. I am trying to use os.chdir to change the directory, ImportHelper to browse for the file and then read the data file. The problem is that the os.chdir does not seem to work at all. There is no error message, and the file browser window opens with the directory of the blend file I started with.
I can browse for the file using ImportHelper and my example program reads the data. However, in my larger code, I would like to read the data in the same operator after I open the file. In this example, TestReadFile works, but when I put the same operator in my larger Addon, the name of the file prints in the system console, but the first line of the file does not and I do not see any error messages. I got around this issue by using one button to get the filename and another button to read the data, but I would prefer to do it all in one operator.
I started with an example I found online. Here is my code:
bl_info = {
"name": "File Read Test",
"author": "Your Name Here",
"version": (1, 0),
"blender": (2, 80, 0),
"location": "File -- Export",
"description": "Tests opening and reading a file",
"warning": "",
"doc_url": "",
"category": "Add Mesh",
}
import bpy
from bpy_extras.io_utils import ExportHelper,ImportHelper
from bpy.types import Operator
import os
class OT_TestOpenFilebrowser(Operator, ImportHelper):
"""Select a file with data to create a shape"""
bl_idname = "myops.open_filebrowser"
bl_label = "Open the file browser (yay)"
def execute(self, context):
os.chdir(r"C:\Users\username\Downloads")
filename, extension = os.path.splitext(self.filepath)
print('Selected file:', filename,extension)
return {'FINISHED'}
class OT_TestReadFile(Operator, ImportHelper):
"""Select a file with data to create a shape"""
bl_idname = "myops.read_file"
bl_label = "Read the first line from the file"
def execute(self, context):
os.chdir(r"C:\Users\Shari\Downloads")
filename, extension = os.path.splitext(self.filepath)
print('Selected file:', filename,extension)
f=open(self.filepath,"r")
datadesc=f.readline() #first line is type of file
print(datadesc)
return {'FINISHED'}
Only needed if you want to add into a dynamic menu
def menu_func_export(self, context):
self.layout.operator("myops.open_filebrowser", text="Test Open File")
self.layout.operator("myops.read_file", text="Test Read File")
def register():
bpy.utils.register_class(OT_TestOpenFilebrowser)
bpy.utils.register_class(OT_TestReadFile)
bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_class(OT_TestOpenFilebrowser)
bpy.utils.unregister_class(OT_ReadFile)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if name == "main":
register()
ImportHelperclass necessarily: https://blender.stackexchange.com/questions/26898/how-to-create-a-folder-file-dialog/26906#26906 otherwise have a look into https://blender.stackexchange.com/questions/229100/how-to-get-filename-and-directory-of-selected-files-in-filebrowser-python/229103#229103 – brockmann Sep 20 '21 at 13:54op = layout.operator(...).directory=that_file_pathThe import operator reads the selected files. This is usual practice. No need for two operators. – batFINGER Sep 20 '21 at 15:18bpy.ops.test.open_filebrowser('INVOKE_DEFAULT', directory="/home/batfinger/Downloads")will open the file browser in Downloads folder. Read the file(s) in the executte method of operator after selected. – batFINGER Sep 20 '21 at 15:33StringPropertycan have a default value. Copy/paste the code from: https://blender.stackexchange.com/questions/26898/how-to-create-a-folder-file-dialog/26906#26906 and set the default attribute to e.g.default="your/fancy/path", which is open up the browser at that specific location and is easy to setup. You can even add a check for all operating systems using python's platform lib: https://stackoverflow.com/a/1857 – brockmann Sep 22 '21 at 12:23