0
$\begingroup$

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()
$\endgroup$
6
  • 2
    $\begingroup$ Sorry, what's your question? How to always open up a specified directory or just allow the user to load an arbitrary file? For the later you do not need the ImportHelper class necessarily: blender.stackexchange.com/questions/26898/… otherwise have a look into blender.stackexchange.com/questions/229100/… $\endgroup$
    – brockmann
    Commented Sep 20, 2021 at 13:54
  • $\begingroup$ Sorry. The main question is that I want to allow the user to choose a file, but open up the file browser at a specific directory. I have also been trying to read a data file after the user chooses a file (currently I have the user choose a file and then press a button to read the data). It works in my example, but the same code is not working in my larger script. $\endgroup$
    – SJK
    Commented Sep 20, 2021 at 14:13
  • $\begingroup$ I just want to control where the user starts looking for the file, and the directory will probably be a string so that can easily be changed. $\endgroup$
    – SJK
    Commented Sep 20, 2021 at 14:19
  • 2
    $\begingroup$ Posted wrong link above, see this one blender.stackexchange.com/a/198926/15543 Test call with bpy.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. $\endgroup$
    – batFINGER
    Commented Sep 20, 2021 at 15:33
  • 1
    $\begingroup$ ... also consider that the StringProperty can have a default value. Copy/paste the code from: blender.stackexchange.com/questions/26898/… 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: stackoverflow.com/a/1857 $\endgroup$
    – brockmann
    Commented Sep 22, 2021 at 12:23

0

You must log in to answer this question.

Browse other questions tagged .