0
$\begingroup$

This question already has an answer here:

I'm updating my addon to 2.80 and I'm stuck with the new register class system. I try to follow the answer here but I'm not good enough as a coder to understand the solution.

The problem comes to register my group properties of my UI panel, here is my code:

import bpy
from bpy.props import (StringProperty,
                   BoolProperty,
                   IntProperty,
                   FloatProperty,
                   EnumProperty,
                   PointerProperty
                   )
from bpy.types import (Panel,
                   Operator,
                   PropertyGroup
                   )

class MySettings(PropertyGroup):

    path : StringProperty(
        name="path",
        description="Path to Directory",
        default="",
        maxlen=1024,
        subtype='DIR_PATH')

    conform_threshold : FloatProperty(
        name="conform_threshold",
        description="A float property",
        default=0.1,
        min=-5,
        max=30.0)

    invert : BoolProperty(
        name="Enable or Disable",
        description="A simple bool property",
        default = False) 


class UI_PT_LynchonPanel(bpy.types.Panel):
    """Las super herramientas de Juan"""
    bl_label = "Lynchon Tools"
    bl_space_type = 'VIEW_3D'
    bl_region_type = "UI"
    bl_category = "Lynchon Tools"

    def draw(self, context):                                                    
####################Y UP##################################
        layout = self.layout
        row = layout.row()
        row.operator("object.y_up") 

         # Create two columns, by using a split layout.####################MET COMPILER##################################

        split = layout.split()
        # First column
        col = split.column()
        col.operator("texture.metal_compiler")

        scn = context.scene
        mytool = scn.my_tool
        col = split.column(align=True)
        col.prop(mytool, 'invert' ,text = "Invert")        

        # Create two columns, by using a split layout. ####################LOW POLY VENUE##################################
        split = layout.split()

        # First column
        col = split.column()
        col.label(text="Import Venue")
        col.operator( "xml.lowpolygeneratorparticles")

        # Second column, aligned
        col = split.column(align=True)
        col.label(text="Conform Venue")
        col.operator( "xml.conform_lp_venue")

        # root for export
        scn = context.scene
        mytool = scn.my_tool
        col = layout.column(align=True)
        col.prop(mytool, "path", text="")

        # Create two columns, by using a split layout.  ####################CONFORM HEIGHT##################################
        split = layout.split()

        # First column
        col = split.column()
        col.operator("xml.conformheight")

        # Second column, aligned
        scn = context.scene
        mytool = scn.my_tool
        col = split.column(align=True)
        col.prop(mytool, "conform_threshold")


def register():
    bpy.utils.register_class(UI_PT_LynchonPanel)
    bpy.utils.register_class(MySettings)
    bpy.types.Scene.my_tool = PointerProperty(type=MySettings)


def unregister():
    bpy.utils.unregister_class(UI_PT_LynchonPanel)
    bpy.utils.unregister_class(MySettings)
    del bpy.types.Scene.my_tool

And the error I'm getting back is this one:

    location: <unknown location>:-1
Traceback (most recent call last):
  File "C:\Users\Juan\AppData\Roaming\Blender Foundation\Blender\2.80\scripts\addons\Lynchon_tools280\UI.py", line 63, in draw
    mytool = scn.my_tool
AttributeError: 'Scene' object has no attribute 'my_tool'

and if I'm not wrong the problem has to do with a register the classes, isn't it?

EDIT

Here my init file which registers all my scrits:

    import bpy

from . UI import UI_PT_LynchonPanel, MySettings
from . xml_parse_conformHeight import XML_OT_conformheight
from . xml_parse_particles import XML_OT_conformLpVenue, XML_OT_lowPolyGeneratorParticles
from . y_up import LynchOperator
from . metal_compiler import metal_compiler


classes = (UI_PT_LynchonPanel, MySettings, XML_OT_conformheight, XML_OT_conformLpVenue, XML_OT_lowPolyGeneratorParticles, LynchOperator, metal_compiler)


register, unregister = bpy.utils.register_classes_factory(classes)
$\endgroup$

marked as duplicate by batFINGER python May 16 at 13:42

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ Your code didn't run the register() at all, that's the problem $\endgroup$ – Hikariztw May 16 at 12:18
  • 1
    $\begingroup$ @Hikariztw it will depend on how it was run. The error implies it has been registered as it is failing in the panel code. Notice It is in the addon path, the register method of an addon module is called when enabled. Quite likely the OP needs to run bpy.ops.script.reload() to update changed addons. (this had the shortcut F8 in 2.7x and before). Or restart blender. Adding the main thread if at bottom is standard and good practice since it will register the addon in text editor. Quite often not so useful in an __init__.py where relative imports will fail. $\endgroup$ – batFINGER May 16 at 12:35
  • $\begingroup$ yes sorry about that, already edited the code $\endgroup$ – Juan Manuel Lynch May 16 at 12:43
  • $\begingroup$ What IMO you want to do is from . import UI and in __init__.py register method call UI.register() otherwise your custom property will not be registered. (hence the issue) $\endgroup$ – batFINGER May 16 at 12:46
  • $\begingroup$ That did work, properties were registered correctly but operators got messed up, I'm getting this error for each operator: C:\Users\Juan\AppData\Roaming\Blender Foundation\Blender\2.80\scripts\addons\Lynchon_tools280\UI.py:83 rna_uiItemO: operator missing srna 'object.y_up' $\endgroup$ – Juan Manuel Lynch May 16 at 12:51
1
$\begingroup$

Did you register it?

EDIT re __init__.py

What IMO you want to do is from . import UI and in __init__.py register method call UI.register() otherwise your custom property will not be registered. (hence the issue seen) Also IMO Ditch using the register factory, it's not that helpful

from . import UI

def register():
    UI.register()

This will call the register method of the UI module.

Former answer below.

Grabbed your code to format it for question edit, added the if __name__ == "__main__" bit to make it register if run in main thread (eg text editor) and ran it and it works fine (apart from not having your custom operators hence the missing buttons in image below)

enter image description here

Edited code.

import bpy
from bpy.props import (StringProperty,
                   BoolProperty,
                   IntProperty,
                   FloatProperty,
                   EnumProperty,
                   PointerProperty
                   )
from bpy.types import (Panel,
                   Operator,
                   PropertyGroup
                   )

class MySettings(PropertyGroup):

    path : StringProperty(
        name="path",
        description="Path to Directory",
        default="",
        maxlen=1024,
        subtype='DIR_PATH')

    conform_threshold : FloatProperty(
        name="conform_threshold",
        description="A float property",
        default=0.1,
        min=-5,
        max=30.0)

    invert : BoolProperty(
        name="Enable or Disable",
        description="A simple bool property",
        default = False) 


class UI_PT_LynchonPanel(bpy.types.Panel):
    """Las super herramientas de Juan"""
    bl_label = "Lynchon Tools"
    bl_space_type = 'VIEW_3D'
    bl_region_type = "UI"
    bl_category = "Lynchon Tools"

    def draw(self, context):
        layout = self.layout

        scn = context.scene
        mytool = scn.my_tool
        row = layout.row()
        row.operator("object.y_up") 


        split = layout.split()
        # First column
        col = split.column()
        col.operator("texture.metal_compiler")

        col = split.column(align=True)
        col.prop(mytool, 'invert' ,text = "Invert")        

        split = layout.split()

        # First column
        col = split.column()
        col.label(text="Import Venue")
        col.operator( "xml.lowpolygeneratorparticles")

        # Second column, aligned
        col = split.column(align=True)
        col.label(text="Conform Venue")
        col.operator( "xml.conform_lp_venue")

        # root for export
        col = layout.column(align=True)
        col.prop(mytool, "path", text="")

        # Create two columns, by using a split layout.  
        split = layout.split()

        # First column
        col = split.column()
        col.operator("xml.conformheight")

        # Second column, aligned
        col = split.column(align=True)
        col.prop(mytool, "conform_threshold")


def register():
    bpy.utils.register_class(UI_PT_LynchonPanel)
    bpy.utils.register_class(MySettings)
    bpy.types.Scene.my_tool = PointerProperty(type=MySettings)


def unregister():
    bpy.utils.unregister_class(UI_PT_LynchonPanel)
    bpy.utils.unregister_class(MySettings)
    del bpy.types.Scene.my_tool

if __name__ == "__main__":
    register()

Note I do not use the blender development addon for vscode from Jaques Lucke,

$\endgroup$
  • $\begingroup$ You are right, it does run from the text editor, that means is a problem from my _init_ file?, please check my edit in the original question. $\endgroup$ – Juan Manuel Lynch May 16 at 12:34
  • $\begingroup$ lol please see my comment under question. $\endgroup$ – batFINGER May 16 at 12:36
  • $\begingroup$ I'm using the blender development addon for vscode from Jaques Lucke, it should update the addon just by saving $\endgroup$ – Juan Manuel Lynch May 16 at 12:42
  • $\begingroup$ I'm sorry to keep bothering you with this issue, but I cant manage to make it right. As you stated adding the def register(): in my __init__ does the job but not from the start, I need to move it after and before my classes register factory then reupdate the addon in order to get everything registered correctly. I know it doesn't make much sense. $\endgroup$ – Juan Manuel Lynch May 16 at 13:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.