I'm making an addon which contains an __init__.py
file, the fu3dm_main.py
file where I place my panel and the fu3dm.py
file where I place all my operators. Two operators in this case.
Here is a working example of the __init__.py
file:
bl_info = {
"name" : "Test - Addon",
"author" : "Simonetos The Greek <[email protected]>",
"description" : "An addon for tests.",
"blender" : (2, 90, 1),
"version" : (1, 0, 0),
"location" : "View3D",
"warning" : "",
"category" : "Generic"
}
import os
import bpy
import bpy.utils.previews
from . fu3dm import *
from . fu3dm_main import *
classes = (
fu3dm.ops.FU3DM_OT_Operator_A,
fu3dm.ops.FU3DM_OT_Operator_B,
fu3dm_main.FU3DM_OP_Main_Panel
)
register, unregister = bpy.utils.register_classes_factory(classes)
The fu3dm_main.py
file:
import bpy
from . fu3dm import *
class fu3dm_main():
"""Main class"""
class FU3DM_OP_Main_Panel(bpy.types.Panel):
"""Main panel class"""
bl_idname = "fu3dm.main_panel"
bl_label = "TEST ADDON"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "FU3DM"
def draw(self, context):
layout = self.layout
row = layout.row()
row.operator("fu3dm.operator_a")
row = layout.row()
row.operator("fu3dm.operator_b")
And the fu3dm.py
file:
import bpy
class fu3dm():
class ops():
"""All operators"""
class FU3DM_OT_Operator_A(bpy.types.Operator):
bl_idname = "fu3dm.operator_a"
bl_label = "Operator A"
bl_description = "..."
bl_options = {'REGISTER','UNDO'}
gender : bpy.props.EnumProperty(name="Gender", description="...", items= [('OP1', "Male", ""), ('OP2', "Female", "")], default='OP1')
def draw(self, context):
layout = self.layout
row = layout.row()
row.label(text="Gender:")
row.prop(self, "gender", text="")
def execute(self, context):
if self.gender == 'OP1':
print('Male')
elif self.gender == 'OP2':
print('Female')
return {"FINISHED"}
class FU3DM_OT_Operator_B(bpy.types.Operator):
bl_idname = "fu3dm.operator_b"
bl_label = "Operator B"
bl_description = "..."
bl_options = {'REGISTER','UNDO'}
face : bpy.props.EnumProperty(name="Face", description="...", items= [('OP1', "Face #1", ""), ('OP2', "Face #2", "")], default='OP1')
def draw(self, context):
layout = self.layout
row = layout.row()
row.label(text="Face:")
row.prop(self, "face", text="")
def execute(self, context):
if fu3dm.ops.FU3DM_OT_Operator_A.gender == "OP1":
print('Male')
# And do something...
elif fu3dm.ops.FU3DM_OT_Operator_A.gender == "OP2":
print('Female')
# And do something...
return {'FINISHED'}
What I want to do is to check if the "gender" EnumProperty
from fu3dm.operator_a
is 'OP1'
or 'OP2'
and then do some things. But I want to do that through fu3dm.operator_b
execute
function.
I tried this if fu3dm.ops.FU3DM_OT_Operator_A.gender == "OP1":
etc, but I got this error AttributeError: type object 'FU3DM_OT_Operator_A' has no attribute 'gender'
. So how can I access this "gender" EnumProperty
but from different operator?
gender
is a property defined via a class annotation , which when registered becomes an operator propertybpy.ops.foo.bar(gender="XX")
orself.gender
in method where self is an instance of the registered operator. It is not a class property.fu3dm.ops.FU3DM_OT_Operator_A.gender == "OP1"
will not work on so many levels. Three or four questions back suggested making $\endgroup$context.preference.addons["foo"]
. $\endgroup$ops.py
other inmain.py
... then if your addon is called fu3dm canfrom fu3dm.ops import Foo
in code anywhere in blender. To me, the way it is, doing little more than wasting 8 columns of precious indent. Consider looking at the way add curve sapling does similar using one "monster" redo panel to generate model based on selections. Or like rigify where you make your selections and then generate based on them instead of "live" via the op. $\endgroup$