0
$\begingroup$

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?

$\endgroup$
5
  • 1
    $\begingroup$ Have tried before to recommend against this nesting of classes to make a psuedo namespace of sorts, and also suggested using a register method per module. At issue here is you are comparing apples and oranges. gender is a property defined via a class annotation , which when registered becomes an operator property bpy.ops.foo.bar(gender="XX") or self.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$
    – batFINGER
    Commented Oct 21, 2020 at 9:56
  • $\begingroup$ preferences in addon prefs or a scene group property, where they would be available from context at any time eg context.preference.addons["foo"]. $\endgroup$
    – batFINGER
    Commented Oct 21, 2020 at 10:00
  • $\begingroup$ Yes I know you are against this nesting classes, I haven't forget that. But how will I tidy up my code? This is just 0,1% of my original code!!! I have to separate so many things in groups (classes and subclasses). If I just put one on top of the other, I'll just create a hell of code. As for "using a register method per module", I plan to do as the example you gave me last time. I just haven't do that yet. Anyway, I'll study again your links and I will change everything... $\endgroup$ Commented Oct 21, 2020 at 10:18
  • $\begingroup$ Would ditch the outer fudm and inner ops and main classes and put operators in ops.py other in main.py ... then if your addon is called fu3dm can from 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$
    – batFINGER
    Commented Oct 21, 2020 at 10:49
  • $\begingroup$ I am remaking it all like you said here (blender.stackexchange.com/questions/183773/…)!!! $\endgroup$ Commented Oct 21, 2020 at 10:58

0

You must log in to answer this question.

Browse other questions tagged .