4
$\begingroup$

I am writing a python script that takes some user input in the operator and does a calculation. The result is three floats, which I would like to display in a nice form like FloatVector but I don’t want them to be editable. This would produce unexpected results. I passed in only a get() function to the parameter constructor to make a read-only result, but now I can’t set the values via code.

What is the ‘blender way’ of showing data to the user in a ui panel, and if there is none, how can I make this work?

$\endgroup$

2 Answers 2

6
$\begingroup$

You can disable the row (makes it read-only) and set emboss to False for example:

def draw(self, context):
    layout = self.layout
    # ...
    row = layout.row()
    row.prop(my_data, "my_prop", emboss=False, text="Values")
    row.enabled = False

Or you can use a label:

    row = layout.row()
    row.label(text="Values: {}".format("  ".join(map(str, my_data.my_prop))))

enter image description here

$\endgroup$
2
  • $\begingroup$ this is perfect! Had no idea about disable row! $\endgroup$
    – user97005
    Commented Jun 15, 2020 at 3:28
  • 1
    $\begingroup$ Thanks for expanding and enhancing my answer @brockmann ;) $\endgroup$
    – Gorgious
    Commented Jun 15, 2020 at 9:10
4
$\begingroup$

Read only property

I passed in only a get() function to the parameter constructor to make a read-only result, but now I can’t set the values via code.

Confused as to why you think cannot just set the value of a read only property in the get method.

Silly example, in the main thread sets the value of _booble_gooble to (1, 2, 3) This value is used by the float property getter.

This way you have a truly read only property, not one that is being masked in the UI, but possibly available to alter in the custom properties.

import bpy
from bpy.props import FloatVectorProperty
from random import random

_booble_gooble = (random(), random(), random())

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

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

        scene = context.scene

        col = layout.column()
        col.prop(scene, "read_only_float")


def random_value(self):
    # self is scene    
    return _booble_gooble

def register():
    bpy.types.Scene.read_only_float = FloatVectorProperty(get=random_value)
    bpy.utils.register_class(HelloWorldPanel)


def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)


if __name__ == "__main__":
    _booble_gooble = (1, 2, 3) # set it
    register()
$\endgroup$

You must log in to answer this question.