# How do you remove a draw handler after it's been added?

I'm making an attempt to use batFINGER's method from this answer for drawing some text on screen without a modal operator, but I'm finding I can't get the text to go away once it's been drawn.

class DrawingClass:
def __init__(self, context, prop):
self.prop = prop
self.handle = bpy.types.SpaceView3D.draw_handler_add(
self.draw_text_callback,(context,),
'WINDOW', 'POST_PIXEL')

def draw_text_callback(self, context):
font_id = 0

sel_obj_1 = (int(bpy.context.selected_objects[0].location[0]))
blf.position(font_id, sel_obj_1, 10, 0)
blf.size(font_id, 12, 72)
blf.draw(font_id, "%s %s" % (context.selected_objects, self.prop))
scene.frame_set(scene.frame_current)

def remove_handle(self):
bpy.types.SpaceView3D.draw_handler_remove(self.handle, 'WINDOW')


I then call the DrawingClass with a checkbox in the UI:

def get_draw_screen(self):
bpy.context.scene.frame_set(bpy.context.scene.frame_current)
return self["vp_draw_screen"]

def set_draw_screen(self, value):
context = bpy.context
test = DrawingClass(context, "TURKEY PALS")
self["vp_draw_screen"] = value
if value:
test
else:
test.remove_handle()
bpy.context.scene.frame_set(bpy.context.scene.frame_current)


When you check the checkbox the name of the selected object will draw on screen and will update with the scene selection, but unchecking the box doesn't stop the text from drawing.

Checking the box again appears to draw a new instance on top of the previous one.

I'm guessing that each time I check the box a new instance of DrawingClass is being created, but I don't know how to access the instance again to remove them.

I've found answers explaining how to remove app handlers like this one here but can't quite figure out how to apply it to this situation.

Thanks for any help!

## 1 Answer

Your method makes a new instance. What you want to do is make some kind of global variable for dc.

Could declare a global variable, make a get set property on some blender class. Another way to do this is to use the driver_namespace

import bpy
import blf

class DrawingClass:
def __init__(self, context, prop):
self.prop = prop
self.handle = bpy.types.SpaceView3D.draw_handler_add(
self.draw_text_callback,(context,),
'WINDOW', 'POST_PIXEL')

def draw_text_callback(self, context):
font_id = 0  # XXX, need to find out how best to get this.

# draw some text
blf.position(font_id, 15, 50, 0)
blf.size(font_id, 20, 72)
blf.draw(font_id, "%s %s" % (context.scene.name, self.prop))

def remove_handle(self):
bpy.types.SpaceView3D.draw_handler_remove(self.handle, 'WINDOW')

context = bpy.context
dns = bpy.app.driver_namespace
dns["dc"] = DrawingClass(context, "Draw This On Screen")


After running the above, can then remove handle from this class with (from py console)

>>> dns = bpy.app.driver_namespace
>>> dc = dns.get("dc")
>>> dc
<__main__.DrawingClass object at 0x7f04830967b8>

>>> dc.remove_handle(
remove_handle(self)
>>> dc.remove_handle()


And the class stops drawing to the screen.

• This worked like a charm! You're a hero! The information on using draw_handlers is really hard to come by so I deeply appreciate the example. Prior to this I had to use a constantly running modal operator to do my drawing because it was the only way I could figure to get the drawing to stop again. Running that operator I would see a spike in CPU usage just from waving the mouse around the viewport from 3% to 14%! Using your method the CPU holds steady at 3%. Thanks again, man. You're a lifesaver. – andyV Mar 21 '17 at 4:08
• Is there a way to delete handle right in the script not in a console? – Mc Gavish Aug 26 '17 at 20:41