2

I have written a function delete_info() which clears the info screen, this works fine when executed from text block. But now I want this function to be called every x seconds. So I am using threading.Timer() function for the same.

import os,bpy
import threading,datetime


def delete_info():
    for window in bpy.context.window_manager.windows:
        screen = window.screen
        for area in screen.areas:
            if area.type == 'INFO':
                info = area

    context = bpy.context
    c = context.copy()
    c["area"] = info

    # # test call
    bpy.ops.info.select_all_toggle(c)
    bpy.ops.info.report_delete(c)

for thing in threading.enumerate():
    if isinstance(thing, threading.Timer):
        thing.cancel()

def set_timer():
  threading.Timer(5.0, set_timer).start()
  delete_info()


set_timer()
#delete_info()

this is the error I get

Exception in thread Thread-248:
Traceback (most recent call last):
  File "/Users/nitish/Downloads/blender-2.76b-OSX_10.6-x86_64/blender.app/Contents/Resources/2.76/python/lib/python3.4/threading.py", line 921, in _bootstrap_inner
    self.run()
  File "/Users/nitish/Downloads/blender-2.76b-OSX_10.6-x86_64/blender.app/Contents/Resources/2.76/python/lib/python3.4/threading.py", line 1187, in run
    self.function(*self.args, **self.kwargs)
  File "/Users/nitish/Desktop/timer.blend/Text", line 26, in set_timer
  File "/Users/nitish/Desktop/timer.blend/Text", line 17, in delete_info
  File "/Users/nitish/Downloads/blender-2.76b-OSX_10.6-x86_64/blender.app/Contents/MacOS/../Resources/2.76/scripts/modules/bpy/ops.py", line 187, in __call__
    ret = op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)
RuntimeError: Operator bpy.ops.info.select_all_toggle.poll() failed, context is incorrect
Nitish Reddy
  • 162
  • 7
  • related https://blenderartists.org/t/how-to-set-correct-context-for-bpy-ops-time-view-all/634779/4 https://blender.stackexchange.com/questions/6101/poll-failed-context-incorrect-example-bpy-ops-view3d-background-image-add – rob Oct 01 '18 at 10:18
  • Related Context and threading don't play nicely together. Suggest using a modal timer operator or this approach might work – batFINGER Oct 01 '18 at 17:14

1 Answers1

0

Threading does not go well with context. Instead use modal timer operator.

def delete_info():
    for window in bpy.context.window_manager.windows:
        screen = window.screen
        for area in screen.areas:
            if area.type == 'INFO':
                info = area

    context = bpy.context
    c = context.copy()
    c["area"] = info

    # # test call
    bpy.ops.info.select_all_toggle(c)
    bpy.ops.info.report_delete(c)

class LoggingTimer(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "myops.logging_timer"
    bl_label = "OPERATOR_LABEL"

    _timer = None

    def modal(self, context, event):



        if event.type == 'TIMER':
            delete_info()


        return {'PASS_THROUGH'}

    def execute(self, context):
        wm = context.window_manager
        self._timer = wm.event_timer_add(300, context.window)
        wm.modal_handler_add(self)
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        wm = context.window_manager
        wm.event_timer_remove(self._timer)

def register():
    bpy.utils.register_class(LoggingTimer)

def unregister():
    bpy.utils.unregister_class(LoggingTimer)

if __name__ == "__main__":
    register()
Nitish Reddy
  • 162
  • 7