How do I append a property or operator to a predefined Blender class?

I would like to add some stuff under the Brush menu while in Texture Paint mode. I know I can completely override the class where these options are housed:

class View3DPaintPanel(UnifiedPaintPanel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    
class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
    bl_category = "Tools"
    bl_label = "Brush"

But of course if I do this I have to include all the code that composes all of the things in them because this method will rewrite said class. This is a bad thing to do for many reasons, but still I’d love to add some stuff under Brush as opposed to creating another menu option to house my buttons, properties, operators etc… Can I just append a function, property or operator to a class instead of completely having to re-write it?

you can prepend and append draw functions:

import bpy

def draw_func_above(self, context):
    layout = self.layout
    
    box = layout.box()
    box.label("Above", icon='TRIA_UP')
    box.prop(context.space_data, "viewport_shade", expand=True)

def draw_func_below(self, context):
    layout = self.layout

    box = layout.box()
    box.label("Below", icon='TRIA_DOWN')
    box.prop(context.space_data, "lock_camera_and_layers")

def register():
    bpy.types.VIEW3D_PT_tools_brush.prepend(draw_func_above)
    bpy.types.VIEW3D_PT_tools_brush.append(draw_func_below)


def unregister():
    bpy.types.VIEW3D_PT_tools_brush.remove(draw_func_above)
    bpy.types.VIEW3D_PT_tools_brush.remove(draw_func_below)


if __name__ == "__main__":
    register()


Dude sweet! Thanks so much.

btw: once you added a custom draw function using append or prepend, there will be a hidden property in the draw function:

bpy.types.VIEW3D_PT_tools_brush.draw._draw_funcs

This is the list of draw function references, and you can do common list actions on it, like re-ordering and popping. Although you shouldn’t play too much with it :wink:

Hey. This is awesome. I’m not entirely sure how to access these references though. When I run that line in the console after running the code I get:

[<function draw_func_above at 0x000000000A4CAD90>,
<function VIEW3D_PT_tools_brush.draw at 0x000000000A614620>,
<function draw_func_below at 0x000000000B1F4F28>]

So basicly, just returned the functions from the code and the default PT_tools_brush one. Not sure if this is what you meant. Is there a means to edit the items in VIEW3D_PT_tools_brush? And do you know what those long numbers are referencing? Would really love to know how to access these.

You just use them?

…draw._draw_funcs[-1] for instance gives the last functions. You could call it, but doesn’t make much sense. …_draw_funs-1

The numbers are memory addresses, although not the actual locations (you usually add the application’s base offset, but it’s probably more complicated actually, maybe read up on heap managers).

You can replace the functions directly in there with other draw functions, or re-order them. There’s nothing really else you can do with it.

Ok, I see. Fair enough. Thanks.