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
$\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$
  • $\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 '13 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 '13 at 7:50
  • $\begingroup$ Thanks again. This is a bit nicer then I was doing with try/except. $\endgroup$ – jasperge Oct 11 '13 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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.