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.
2 Answers
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)
-
$\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 matchbl_label
of the attribute (if it exists) to a string (e.g. 'my tools'). Is there a better way to find a Panel bybl_label
instead of the class name? $\endgroup$– jaspergeOct 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_tOct 11, 2013 at 7:50
-
$\begingroup$ Thanks again. This is a bit nicer then I was doing with
try
/except
. $\endgroup$– jaspergeOct 11, 2013 at 8:27
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