-1
$\begingroup$

enter image description here

import bpy 
a=0 
    
def in_5_seconds(): 
    a=1 
    print(a) 

if a==1: 
    bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0)) 


bpy.app.timers.register(in_5_seconds, first_interval=5) 

I want to create a cube in 5 seconds.

I changed the value of a to 1 using the def command in the system console, but the cube is not created.

Please tell me a solution

$\endgroup$
6
  • $\begingroup$ The code is ok, but indents are wrong (in screen capture). I've corrected it editing the question. $\endgroup$ – lemon Sep 17 '20 at 14:58
  • 1
    $\begingroup$ Print out context, print(context.copy()) and will notice many not available ie have None values when run from a timer thread. See blender.stackexchange.com/questions/135970/… See the modal timer template in text editor for another way to wait to delay an operator running which will have context. $\endgroup$ – batFINGER Sep 17 '20 at 14:58
  • $\begingroup$ @lemon I find the current version of the question to be very confusing. Why have two versions of the code with commentary about the changes? The first version shouldn't be in the question at all based on the code shown in the screenshot. Fixing that indentation maybe part of (or all of) an answer. $\endgroup$ – Matt Sep 17 '20 at 18:56
  • $\begingroup$ @Matt, look at the edit history. The first version did not used code sample formatting. $\endgroup$ – lemon Sep 18 '20 at 5:34
  • $\begingroup$ @lemon Yes... I'm aware. The edit history exists to show the edit history, and shouldnt be necessary to understand the question. It is redundant and confusing for the question to also show an edit history. It is also inappropriate for edits to fundamentally change the question, as yours has done. Your edit should have fixed the formatting to be consistent with the screenshot and nothing else. By changing the indentation from what is in the screenshot you changed the question. $\endgroup$ – Matt Sep 18 '20 at 11:16
1
$\begingroup$

Modal Timer Operator.

For original code, the operator will never be called. Putting a print in the if statement will show it is never run. If the if clause was true; operator would be called once, when the script is run or imported. It is not run again when the timer method is called after 5 seconds. Suggest googling (stackoverflow) "python variable scope". I imagine this is why @lemon edited, thinking it may be a pasting error.

However the @lemon edited script with indent wont work see: Context is incorrect when calling from a timer

Instead could use a modal timer operator, when a number of seconds has elapsed, call the add primitive cube operator and finish.

How to run a python script at regular intervals?

Edited version of Text Editor > Templates > Python > Operator Modal Timer

import bpy
from bpy.props import IntProperty


class ModalTimerOperator(bpy.types.Operator):
    """Operator which runs its self from a timer"""
    bl_idname = "wm.modal_timer_operator"
    bl_label = "Modal Timer Operator"

    _timer = None
    
    delay: IntProperty(
        name="Delay",
        default=10,
        )
        
    def modal(self, context, event):
        if event.type == 'TIMER':
            
            if self._timer.time_duration >= self.delay:
                print(
                    "Cube added after ",
                     self._timer.time_duration,
                     "secs")
                # remove timer
                self.cancel(context)
                # call the operator, return its status
                return bpy.ops.mesh.primitive_cube_add()
                    
        return {'PASS_THROUGH'}

    def execute(self, context):
        wm = context.window_manager
        self._timer = wm.event_timer_add(self.delay, window=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(ModalTimerOperator)


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


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.wm.modal_timer_operator(delay=5)

Test run

Cube added after  5.001951217651367 secs
$\endgroup$
2
  • $\begingroup$ FYI I edited the code because it had no indent at all as not formatted. Though tested it and obtained the cube. $\endgroup$ – lemon Sep 18 '20 at 5:38
  • 1
    $\begingroup$ Thanks for the FYI. Would have done same. btw Appears to have a en.wikipedia.org/wiki/Zero-width_space <200b>if a Anyway FWIW (zero?) editing code and running such that timer does call operator, for me on linux results in seg fault. Would recommend not using context or operators from a threaded timer and use a modal timer. $\endgroup$ – batFINGER Sep 18 '20 at 7:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.