Reputation: 58
I am trying to make a script, that reads a .txt (where .obj names are stored), then makes costum - buttons in blender. If you click one of the buttons, it should open the file according to the name in the txt.
It works, but will only open the last obj on the list.
How can I fix it? I want this to work!
My code so far:
import bpy
class directoryPan(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_label = "Biblio"
bl_category = "Import" #
def draw(self, context):
self.layout.row().label("Import :")
self.layout.operator("import.stuff", icon ='FILE')
obj_list = []
biblio_one = open("C:\\Users\\Jasmin\\Desktop\\liste.txt")
for line in biblio_one:
obj_list.append(line.rstrip())
biblio_one.close()
print("start")
for i in obj_list:
newbutton = i
import_obj = "import." + i
self.layout.operator(import_obj, icon ='FILE')
######
class ScanFileOperator(bpy.types.Operator):
bl_idname = import_obj
bl_label = newbutton
def execute(self, context):
pfad = "C:\\Users\\Jasmin\\Desktop\\" + newbutton+ ".obj" ###
bpy.ops.import_scene.obj(filepath= pfad, filter_glob="*.obj;*.mtl", use_ngons=True, use_edges=True, use_smooth_groups=True, use_split_objects=True, use_split_groups=True, use_groups_as_vgroups=False, use_image_search=True, split_mode='ON', global_clamp_size=0, axis_forward='-Z', axis_up='Y')
bpy.ops.object.origin_set(type = 'GEOMETRY_ORIGIN')
return {'FINISH'}
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()
I know that the problem is newbutton, because after the loop,that draws the buttons, it has the value of the last item in the list. But I don't know how to fix it.
Upvotes: 2
Views: 311
Reputation: 7079
In blender's interface a button is linked to an operator, clicking the button causes the operator to perform it's task. Rather than generating a new operator for each button, a better approach would be to add a property to the operator and set the property used for each button.
By adding a bpy.props
to the operator class you get a property that can be set for each button as it is displayed in the panel and can then be accessed when the operator is run.
class ScanFileOperator(bpy.types.Operator):
'''Import an obj into the current scene'''
bl_idname = 'import.scanfile'
bl_label = 'Import an obj'
bl_options = {'REGISTER', 'UNDO'}
objfile = bpy.props.StringProperty(name="obj filename")
def execute(self, context):
print('importing', self.objfile)
return {'FINISHED'}
class directoryPan(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_label = "Biblio"
bl_category = "Import"
def draw(self, context):
col = self.layout.column()
col.label("Import :")
obj_list = []
biblio_one = ['obj1','obj2','obj3','obj4','obj5',]
for line in biblio_one:
obj_list.append(line.rstrip())
for i in obj_list:
import_obj = "import." + i
col.operator('import.scanfile', text='Import - '+i,
icon ='FILE').objfile = import_obj
Upvotes: 1
Reputation: 520
I haven't loaded the code to test this, but from what I can see newbutton is one variable. The for loop keeps setting the same variable over and over. That's why you only get the last value in the list.
What you might want to do is define a function that instantiates your object. The function would require all of the parameters needed to build that object to the scene. Calling that function for each iteration of the loop would instantiate a new obect to the scene with the expected data since each object would encapsulate the parameters that you pass to it.
I hope that helps!
Upvotes: 1