4
$\begingroup$

I would like to query the panels in the Tool Shelf, regardless of the context. Also I would like to query the tools that are in a certain panel. The idea is that my script can check if a certain panel is already there (preferably by matching the bl_label) and add certain functions to the panel if they don't already exist.

$\endgroup$

2 Answers 2

2
$\begingroup$

Panels are registered by type and are not accessible as instances in the Blender data. Instead you should check the bpy.types list for an existing panel type:

>>> hasattr(bpy.types, "OBJECT_PT_relations")
True

>>> hasattr(bpy.types, "OBJECT_PT_funky_feature")
False

You can also iterate over bpy.types with dir(), so you can for example find a panel by it's bl_label. This works fine if you use some utility functions:

def panel_types():
basetype = bpy.types.Panel
for typename in dir(bpy.types):
    btype = getattr(bpy.types, typename)
    if issubclass(btype, basetype):
        yield btype

def panels_by_label(label):
    for ptype in panel_types():
        if getattr(ptype.bl_rna, "bl_label", None) == label:
            yield ptype

print([p.bl_rna.identifier for p in panels_by_label("Relations")])

If you want to extend a panel with own buttons you can append a draw function:

def draw_my_buttons(self, context):
    # Suppose we have defined this operator
    self.layout.operator("funky_feature.my_own_operator")

# Example: extend the "Relations" object panel
bpy.types.OBJECT_PT_relations.append(draw_my_buttons)

If you intend to make this into an addon you should clean up the original Blender type on unregistering:

bpy.types.OBJECT_PT_relations.remove(draw_my_buttons)
$\endgroup$
3
  • $\begingroup$ I'm now using dir(bpy.types) to get a list of all the attributes. Then I use this list to iterate over all attributes and try to match bl_label of the attribute (if it exists) to a string (e.g. 'my tools'). Is there a better way to find a Panel by bl_label instead of the class name? $\endgroup$
    – jasperge
    Oct 10, 2013 at 21:50
  • 1
    $\begingroup$ AFAIK there is currently no nicer way to iterate over types than using dir(), but it works ok with some utility functions: pasteall.org/46396/python $\endgroup$
    – lukas_t
    Oct 11, 2013 at 7:50
  • $\begingroup$ Thanks again. This is a bit nicer then I was doing with try/except. $\endgroup$
    – jasperge
    Oct 11, 2013 at 8:27
3
$\begingroup$

If you wanna check the appended (or prepended) draw functions of another addons, added to built-in panels, you can do for example:

draw_method = bpy.types.OBJECT_OT_relations.draw
if hasattr(draw_method, "_draw_funcs"):
    print(draw_method._draw_funcs)

As soon as a custom draw function is added, _draw_funcs will be defined and contain a list of draw functions. They are stored in a list, which means you can pop/remove/insert/append/prepend or shuffle the entries.

A really advanced possibility is to intercept all draw calls, but beware! Only a single addon may do this at a time, or you'll run into errors.

http://wiki.blender.org/index.php/User:Ideasman42/Blender_UI_Shenanigans

$\endgroup$

You must log in to answer this question.

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