I needed a Help in Drawing a Property Group, I created a Color ramp in Line 78 and needed Control for the Slider and for that I assigned this to the position_control in line number 85. and I wanted to draw the Slider of that position Control and I tried following this to create this

I just Made the Class for Float Value but perhaps I am facing the Issue in Registering at the end as I don't know how to do this as this error is shown -

Traceback (most recent call last): File "\TEST_MATERIAL.py", line 158, in AttributeError: ramp_pos Error: Python script failed, check the message in the system console

Can anyone help me with this problem?

bl_info = {
"name": "Add Test Material",
"author": "Rakesh Choudhary",
"version": (1, 0),
"blender": (2, 83, 0),
"location": "View3D > Sidebar > Test Material Node",
"description": "Click on the 'Test Material' button to add a material to your object.",
"warning": "",
"wiki_url": "",
"category": "3D View"

import bpy
from bpy.types import (
from bpy.props import (

class TEST_MATERIAL_OT_add_material(Operator):
    bl_idname = "test_material.add_material"
    bl_label = "Add Test Material"
    bl_description = "This button will add a material to your object"

    def execute(self, context):
        return {'FINISHED'}

    def create_material(self):
        test_shader_mat = bpy.data.materials.new("TestMat")
        mesh = bpy.context.object.data
        bpy.context.object.active_material.use_nodes = True

        for mat in bpy.data.materials:
            if "TestMat" in mat.name:
                nodes = mat.node_tree.nodes
                for node in nodes:
                    if node.type != 'OUTPUT_MATERIAL':  # skip the material output node as we'll need it later

        # Creating Node Group Test_Material
        group = bpy.data.node_groups.new(type="ShaderNodeTree", name="Test_Material")

        # Creating Group Input
        group.inputs.new("NodeSocketColor", "Diffuse Color")
        group.inputs.new("NodeSocketColor", "Glossy Color")
        group.inputs.new("NodeSocketFloat", "Glossyness")
        input_node = group.nodes.new("NodeGroupInput")
        input_node.location = (-800, 0)

        # Creating Group Output Node
        group.outputs.new("NodeSocketShader", "Diffuse Color")
        group.outputs.new("NodeSocketShader", "Glossy Color")
        group.outputs.new("NodeSocketShader", "Mix Output")

        output_node = group.nodes.new("NodeGroupOutput")
        output_node.location = (1500, 0)

        # Creating Diffuse Node
        diffuse_node = group.nodes.new(type='ShaderNodeBsdfDiffuse')
        diffuse_node.location = (150, 100)

        # Creating Glossy Node
        glossy_node = group.nodes.new(type='ShaderNodeBsdfGlossy')
        glossy_node.location = (300, 250)

        # Creating Mix Shader Node
        mix_shader_node = group.nodes.new(type='ShaderNodeMixShader')
        mix_shader_node.location = (450, 100)
        #Creating Color Ramp
        col_ramp = group.nodes.new(type="ShaderNodeValToRGB")
        col_ramp.location = (400, -300)
        col_ramp.color_ramp.elements[0].color = (0,0,0,1)
        position_control = col_ramp.color_ramp.elements[0].position

        col_ramp.color_ramp.elements[1].position = (1.0)
        col_ramp.color_ramp.elements[1].color = (1, 1, 1, 1)

        # Creating Links Between Nodes
        group.links.new(diffuse_node.outputs["BSDF"], mix_shader_node.inputs[1])
        group.links.new(glossy_node.outputs["BSDF"], mix_shader_node.inputs[2])
        group.links.new(input_node.outputs["Diffuse Color"], diffuse_node.inputs[0])
        group.links.new(input_node.outputs["Glossy Color"], glossy_node.inputs[0])
        group.links.new(input_node.outputs["Glossyness"], glossy_node.inputs[1])
        group.links.new(output_node.inputs["Diffuse Color"], diffuse_node.outputs[0])
        group.links.new(output_node.inputs["Glossy Color"], glossy_node.outputs[0])
        group.links.new(output_node.inputs["Mix Output"], mix_shader_node.outputs[0])
        group.links.new(col_ramp.outputs["Color"], mix_shader_node.inputs[0])

        # Putting Node Group to the node editor
        tree = bpy.context.object.active_material.node_tree
        group_node = tree.nodes.new("ShaderNodeGroup")
        group_node.node_tree = group
        group_node.location = (-40, 300)
        group_node.use_custom_color = True
        group_node.color = (1, 0.341, 0.034)
        group_node.width = 250

        shader_node_output_material_node = tree.nodes["Material Output"]
        links = tree.links
        links.new(group_node.outputs[0], shader_node_output_material_node.inputs[0])
class Col_ramp_Property(PropertyGroup):
   ramp_pos : FloatProperty(
       name = "Position",
       description = "A float property",
       default = 0.75,
       min = 0.01,
       max = 1.0

class TEST_MATERIAL_PT_layout_panel(Panel):
    bl_label = "Test Material Node"
    bl_category = "Test Material"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"

    def draw(self, context):
        layout = self.layout
        C = bpy.context
        position_control = C.active_object.active_material.node_tree.nodes.col_ramp.color_ramp.elements[0].position
        layout.operator("test_material.add_material", icon='IMPORT')
        row = layout.row()
        row.prop(position_control, "ramp_pos")

classes = (TEST_MATERIAL_OT_add_material, Col_ramp_Property, TEST_MATERIAL_PT_layout_panel)

def register():
    for cls in classes:
    bpy.types.Scene.ramp_pos = PointerProperty(type=Col_ramp_Property)


def unregister():
    for cls in classes:
    del bpy.types.Scene.ramp_pos

if __name__ == "__main__":

I set C = bpy.context

position_control = C.active_object.active_material.node_tree.nodes.col_ramp.color_ramp.elements[0].position

and still there is the same problem, I think the main problem is I couldn't find the correct path to(how to access) the colorramp's element's position

enter image description here

  • 2
    $\begingroup$ Read Robert's comment carefully. One obvious issue: "Col_ramp_Property" is a string right? ...and you actually have to assign a class type... Again, recommend to take a basic python course. $\endgroup$
    – brockmann
    Jun 17, 2020 at 14:50
  • 3
    $\begingroup$ Try to understand what you're doing. You are assigning a string to type: type="Col_ramp_Property". Assign the actual class type: type=Col_ramp_Property. Do you get the difference now? $\endgroup$
    – brockmann
    Jun 17, 2020 at 17:55
  • 2
    $\begingroup$ I guess complete error message is: position_control has no attribute ramp_pos. Question is: Where position_control variable comes from? Not declared in the panel class... $\endgroup$
    – brockmann
    Jun 17, 2020 at 18:30
  • 2
    $\begingroup$ Have a look how this is done over here in OBJECT_PT_CustomPanel class. $\endgroup$
    – brockmann
    Jun 17, 2020 at 19:14
  • 2
    $\begingroup$ Please don't change your question each time - Imagine someone is already writing an answer (at the moment) and you are changing the question that drastically, it's a waste of time and not fair. This also means that if you can draw the property, we are done here IMHO. I suggest ask a new question on how to do... @Rakeshchoudhary $\endgroup$
    – brockmann
    Jun 18, 2020 at 9:22


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.