How to target non-selected objects in the scene?

I know I can use:

for obj in bpy.context.selected_objects:

to target the selected objects in a scene.

I have a silly question: how do I fire an event where when the user clicks (selects) on an object or adds to the current selection of objects, the script alters the properties of any unselected object in the 3d view? I have little experience with Python in Blender, and can’t seem to figure that out.

There maybe a smarter way to do this but it seemed to work, this makes a list from all selectable objects in the scene, and a list of your selected objects, then pops whatevers in the selected list from the selectable list

import bpy

nonSelectList = bpy.context.selectable_objects
selectList = bpy.context.selected_objects

for obj in selectList:
nonSelectList.pop(nonSelectList.index(obj))

for obj in nonSelectList:
print(obj.name)
// your code on non selected objects here

edit: the other part of you question, how to have python fire an event when you select an object, I’m not really how to do this yet either.
edit2: edited the code in my example, realized it had the wrong list in the pop method, it would work sometimes but not every times

Thanks for your response! I have a lot of experience with web coding, and know my way around Python for Web projects, but for some reason I am a bit lost in how to start coding stuff in Blender. The documentation is a bit confusing to me.

I guess I will have to dig some more to see if I can find the info I need, or examine someone else’s addons.

I am not sure if there is an event generated for selecting objects but you could setup a timer and poll the selection state of all objects.

If you have not checked out the Tempates menu of the Text Editor window, give it a look. There are a lot of working examples. One might fit your needs.

You can address any object by name without using the context at all.


name = "Cube"
ob = bpy.data.objects.get(name)
if ob != None:
    # Object exists.
    if ob.selected == True:
        # Object is selected
        pass
else:
    # Object does not exist.
    pass

I am not sure if there is an event generated for selecting objects

No, see
http://www.blender.org/documentation/blender_python_api_2_69_1/info_quickstart.html

Kinda hacky, but I’ve slipped something in my draw method to detect object selection.

Yes, I read the same docs, and it seems that no event is fired when an object is selected that can be listened to through Pyhton:

The Blender/Python API can’t (yet)…

  • Create new space types.
  • Assign custom properties to every type.
  • Define callbacks or listeners to be notified when data is changed.

Anyway, the functionality I was trying to implement is this:

  • turn off outline selected
  • turn on bound box for selected objects only.

This way the selection of more complex objects would not severely impact the viewport’s performance at all, and we could still have a visual cue that one or multiple objects are selected. But no luck binding these actions to a select object event.

Pretty simple python script, and I was able to write a couple of lines that run and check for selected and unselected objects and turn on/off bounding box respectively (with the help of above posts).

Ideally this should be an option in the preferences: a selection method by “outline selected” or “bounding box”.

you can append a callback to the app handler scene_update_pre / post and detect selection changes I guess, not sure if selection state is changed inbetween. If no, register a prop like

bpy.types.Object.select_last = bpy.props.BoolProperty()

and compare current Object.select to it, then set select_last to select.

Note that this app handler will be called around 20 times per second (not sure how it behaves on other platforms than windows). So keep in mind that it might slow down blender - although it may not be a problem at all (i suggest you do timing checks).

As of whenever you can use a property


import bpy


def get_unselected_objects(self):    
    return [obj for obj in self.scene.objects if obj not in self.selected_objects]


bpy.types.Context.unselected_objects = property(get_unselected_objects)


>>> C.unselected_objects
[bpy.data.objects['Cube'], bpy.data.objects['Camera']]

And to see if a selection has changed


import bpy


_selections = []


def get_selection_change(self):
    global _selections
    if self.selected_objects != _selections:
        _selections = self.selected_objects
        return True
    return False


bpy.types.Context.selection_change = property(get_selection_change)