8
$\begingroup$

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!

$\endgroup$

1 Answer 1

14
$\begingroup$

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.

$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$
    – andyV
    Commented Mar 21, 2017 at 4:08
  • 1
    $\begingroup$ Is there a way to delete handle right in the script not in a console? $\endgroup$
    – Mc Gavish
    Commented Aug 26, 2017 at 20:41

You must log in to answer this question.

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