2
$\begingroup$

I am trying to create a simple script in python that will allow me to select objects from my scene. What I did, is created a scene, and added 3 objects, a cube, a sphere and a cylinder, and they are named; Cube, Sphere and a Cylinder , respectively. I am trying to create a python script in which I want to select these objects within a time delay. So for example I want to select the Cylinder, then 1 second later I want to select the Cube and then 1 second after that I want to select the Sphere. At the end of my script all 3 objects should be selected. In my script they are all getting selected but they all get selected instantaneously at the end of the program. I used the time module for python to create the time delay of 1 second after I select one object, but it doesn't seem like the time delay does anything, because all 3 objects gets selected simultaneously. Here is my python script and blender project. enter image description here

Firstly, I create an empty list, which i then fill up with the name of all the objects in my scene, in my case its only 3 objects. I then loop through those objects from my list / scene and select them 1 by 1 with a 1 second delay in between. However when the script ends all the objects are selected instantly. And yes, I did unselect everything before running the script.

Does anyone know how I can fix or re write my code, so when I run the script, it will select an object then wait for 1 second and select the other object and then wait 1 more second after that and select the last object.

Of course, I only used only 3 objects in my scene for simplicity reasons, but this script should of course work for any scene and any number of objects.

$\endgroup$

2 Answers 2

4
$\begingroup$

Modal timer operator

Would suggest not using time.sleep and use a modal timer operator instead.' Example using modal timer operator template.

import bpy

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
    ob_index = 0

    def modal(self, context, event):
        scene = context.scene
        if self.ob_index >= len(scene.objects):
            self.cancel(context)
            return {'CANCELLED'}

        if event.type == 'TIMER':
            scene.objects[self.ob_index].select = True
            self.ob_index += 1

        return {'PASS_THROUGH'}

    def execute(self, context):
        wm = context.window_manager
        self._timer = wm.event_timer_add(1, 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()
$\endgroup$
4
  • $\begingroup$ Yes, this is what I am looking for exactly ! I only have one question, how will I be able to use this Modal time operator ? Do I just use this same code at the beginning of my script and then run my script as it is, or do I need to apply some parameters ? $\endgroup$ Commented Nov 28, 2017 at 15:48
  • $\begingroup$ Yes, I got it working, just by running your script ! I am pretty new to python, but could you shed some light on how and why does this modal time operator works ? $\endgroup$ Commented Nov 28, 2017 at 15:55
  • 1
    $\begingroup$ Will get back to it.. need new batteries for keyboard.. took 5 mins to write this comment lol. $\endgroup$
    – batFINGER
    Commented Nov 28, 2017 at 15:58
  • $\begingroup$ Yeah, don't worry! $\endgroup$ Commented Nov 28, 2017 at 15:59
0
$\begingroup$

It ought to function as intended. Try printing time between iterations.

test it

$\endgroup$
7
  • $\begingroup$ Did it work for you ? $\endgroup$ Commented Nov 28, 2017 at 1:57
  • 1
    $\begingroup$ Yeah, it did OK over here. I can't say why it would jump past a delay for you. You've got the most recent version of Blender? $\endgroup$ Commented Nov 28, 2017 at 2:21
  • $\begingroup$ I am using 2.78b. $\endgroup$ Commented Nov 28, 2017 at 2:50
  • $\begingroup$ Possibly due to Python output buffering, using multiple threads to go through the loop. stackoverflow.com/questions/21886233/… Maybe import sys then call sys.stdout.flush() after sleep stackoverflow.com/questions/44799353/… $\endgroup$ Commented Nov 28, 2017 at 3:24
  • 1
    $\begingroup$ It waits for me. Printing time ticks once a second, as shown in the image above. Seems like a Python bug, but I can't recreate it here. Could be due to processor or OS, couldn't say. You might try asking on stackoverflow, and see if someone over there has a better idea of what's going on. I'd imagine they'll point you to similar pages, but maybe they can explain it better. $\endgroup$ Commented Nov 28, 2017 at 5:20

You must log in to answer this question.

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