3
$\begingroup$

I have found this thread and several other threads but nothing with any legit answers. We can somewhat select a collection using for example this script that "selects" the one at index 2:

collections = bpy.context.view_layer.layer_collection.children
bpy.context.view_layer.active_layer_collection = collections[2]

But that doesn't fully select the collection as can be seen below. It is not blue in highlight. This can be proven when you press F2 in the Outliner, it will attempt to rename the one in blue highlight instead of the supposedly newly "selected" collection.

enter image description here

When I click a collection I see the command bpy.ops.outliner.item_activate(deselect_all=True) but adding this to the script doesn't help. How do you fully select a collection with python or is this even possible? The solution for this question will help solve this thread.

$\endgroup$
3
  • $\begingroup$ Does the accepted answer here: blender.stackexchange.com/questions/127403/… help? $\endgroup$
    – curious_1
    Oct 2 at 10:12
  • $\begingroup$ @curious_1 no it does the same thing, no blue highlight, just the white highlight. the code in the accepted answer is even worse with the unnecessary iteration i think. $\endgroup$ Oct 3 at 1:24
  • 1
    $\begingroup$ As you witnessed the iteration is because of nested collections, in a trivial case with rank 1 children it isn't useful since they can be accessed easily. I think you've hit the same design roadblock as I did some time ago, the outliner / view layer python API is lacking several utility functions to access and manage layer collections. $\endgroup$
    – Gorgious
    Oct 3 at 8:36

2 Answers 2

6
$\begingroup$

Each outliner area has individual selection (blue highlight).

But only one active collection as seen below (gray highlight on icon).

enter image description here

If you press F2 in any one area, it renames the active selection in the area where your mouse is on. But if you create an object, it will always be created under the active collection.

The bpy.ops.outliner.item_activate(extend=False, extend_range=False, deselect_all=False) operator internally uses mouse position to select and activate items.

Also there is no active_item like attribute associated with the OUTLINER space you can use. enter image description here

So you can't use python to manipulate active selection in the OUTLINER.

However you can use bpy.data.collections to modify collection properties.

Please do tell what you cannot achieve without that selection.

If you want to rename a collection using python use any one of these:

bpy.data.collections[0].name = "new_name"
bpy.data.collections['current_name'].name = "new_name"
$\endgroup$
4
  • $\begingroup$ Do you use some addon to display all available attributes of an area? BTW, maybe bpy.ops.outliner.item_activate() could be run with proper context override... $\endgroup$ Oct 2 at 19:10
  • 2
    $\begingroup$ @MarkusvonBroady API_Browser $\endgroup$
    – JayReigns
    Oct 2 at 21:04
  • $\begingroup$ i initially downvoted the answer because it did not answer the question but now with the added details, i can make more sense of the situation and now upvoted it, thank you very much! $\endgroup$ Oct 3 at 1:32
  • $\begingroup$ ok so basically the answer to my question is that it is impossible to change the active selection via python. $\endgroup$ Oct 3 at 2:19
-1
$\begingroup$

ok so basically the answer to my question is that it is impossible to change the active selection via python.

-> Technically this is possible.

-> Your question was "How can I fully select a collection using python with blue highlight?"

-> Your question does not mention a specific api to be required as part of the solution to the problem you stated in your question.

So an Answer is:

import pyautogui
import time
import pydirectinput
 
##assumes that u work in 1080p and with the standard window-arrangement in blender 3.6
x, y = 1655, 105
pyautogui.moveTo(x, y)
pyautogui.click(button='left')
# Wait for a moment
time.sleep(0.5)
# Simulate a scroll down
pyautogui.scroll(-5000)
time.sleep(0.5)
pyautogui.moveTo(x, 340)
time.sleep(0.5)
pydirectinput.keyDown('shift')
pyautogui.click(button='left')
pydirectinput.keyUp('shift')
```
$\endgroup$
6
  • $\begingroup$ It's a very "ugly" solution. Plus it will fail in most cases, because of the coordinates so it doesn't actually work. Technically, it exists, yes, but if you judged this as an advice to a friend who is looking for help with this... Well, it's a terrible advice. Deserves a downvote the way I see it... $\endgroup$ Nov 13 at 15:13
  • $\begingroup$ beauty is in the eye of the beholder. $\endgroup$ Nov 13 at 15:16
  • $\begingroup$ If you hover over the downvote button it has a tooltip that says: "This answer is not useful". I think it fits. It's my honest vote. Maybe others will find it useful and upvote. $\endgroup$ Nov 13 at 15:37
  • 2
    $\begingroup$ It being not elegant is not the only reason I think it's not useful. It will not work in most cases because it's based on pixel coordinates and UI state. It is not useful for average user and it is not useful as a Python solution because it could not be used in an add-on. "How about putting some brains into getting up a solution yourself" - a good solution does not seem to exist in this case. Blender's Python API does not seem to have functionality for this. $\endgroup$ Nov 13 at 16:39
  • 3
    $\begingroup$ If I was to give an "ugly" solution, I think I would try to explore bpy.ops.outliner.select_walk() operator. It seems to make the highlighted collection active so it should be possible to do it until the needed one is selected, but that is also not a good solution... $\endgroup$ Nov 13 at 16:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .