5
$\begingroup$

If creating a basic operator and reading the list of selected objects upon execute I get the correct response:

class foo(bpy.types.Operator):
    bl_label  = "foo"
    bl_idname = "foo"

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

However I need to read the list of selected objects elsewhere, outside of the Operator, from within a subclass of threading.Thread.

Calling bpy.context.selected_objects anywhere else results in an error, as it doesn't exist.. which is both puzzling and irritating.

Has anyone else dealt with situation before, not being able to access the list of selected objects. Is there by chance another method?

I have thought about creating an operator that would return the list of selected objects if invoked through python code... but I do not understand operators fully (yet) and thus do not know if that is possible.

$\endgroup$
1
  • 1
    $\begingroup$ Why threading? bpy is not thread-safe, so that might be the root cause. $\endgroup$ Commented Aug 25, 2015 at 0:29

2 Answers 2

3
$\begingroup$

The context is dependent on quite a number of things, and not every context holds the scene's set of selected_objects. A safer and more consistent way to get the selected objects is this:

selected_objects = [ o for o in bpy.context.scene.objects if o.select ]
$\endgroup$
2
  • 1
    $\begingroup$ I wonder if there is a performance difference between bpy.context.selected_objects and o for o in bpy.context.scene.objects if o.select Given a scene may have thousands of objects an only two possibly selected (or any arbitrary number). $\endgroup$ Commented Aug 24, 2015 at 14:27
  • 3
    $\begingroup$ List comprehensions are fast, much faster than loops and among the fastest operations python offers. I doubt it will add much to the runtime even if context.selected_objects is faster. $\endgroup$ Commented Aug 24, 2015 at 14:37
2
$\begingroup$

The biggest catch with bpy.context is usually with operators that work in the 3dview but fail when trying to run them from the python console or when running a script in the text editor.

To overcome these issues you can override the context, which is described on the bpy.ops page, you may also want to look at several examples in answers here. While ways to override the context are designed as a way to pass on the adjusted context to an operator, the concept should translate to your use of threads, maybe you will need to pass a starting context for the thread to use when you first start it.

$\endgroup$
1
  • $\begingroup$ I'm having the exact same problem but I'm struggling with overriding context. I want to apply "Smart UV Project" and no matter what/how I make context its always wrong. Can you ping any hints how to handle it ? $\endgroup$ Commented Oct 5, 2020 at 20:31

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.