13
$\begingroup$

I would like to create a script that runs constantly throughout the life of a Blender session. The problem is that Blender's interface "blocks" while the script is running. As a trivial example, if I run the code below:

while True:
    continue

Then Blender freezes up, and I have to use xkill to stop it. How may I create a script that may be running constantly but does not stop Blender from functioning normally?

$\endgroup$
  • 2
    $\begingroup$ If you start blender from a terminal, you can press Ctrl+C in the terminal to cancel the script, I wouldn't expect users to do this, but its a better alternative to xkill and you wont lose your work. $\endgroup$ – ideasman42 Jun 1 '13 at 4:56
8
$\begingroup$

What you are looking for is to create a modal operator. From the Wiki:

A modal operator defines a Operator.modal function which running, handling events until it returns {'FINISHED'} or {'CANCELLED'}. Grab, Rotate, Scale and Fly-Mode are examples of modal operators. They are especially useful for interactive tools, your operator can have its own state where keys toggle options as the operator runs.

There is a template for the Modal Operator accessible from the Blender Text Editor. Modal Operator

$\endgroup$
  • 4
    $\begingroup$ Just recently I answered this question on SO: stackoverflow.com/a/16744008/2419030 You'll find a link to a modal operator example, along with the use of Python timers. Essentially you'll be creating a modal operator for what you're doing. If you want to poll stuff like network interface or other things, you can do that easily by checking for those in the modal implementation of your operator. Check the Conways Game Of Life example implementation linked in the SO answer. Short video of it is here: youtube.com/watch?v=kdw7CTQsQmI $\endgroup$ – jesterKing May 29 '13 at 21:37
1
$\begingroup$

Instead of running your code continuously all of the time, consider either running it periodically (every x seconds, etc), or only calling it when a specific event comes up.

The standard technique to use to get your code snippet to run periodically is to use the threading module. For example:

import threading

def my_func():
    threading.Timer(number_of_seconds, my_func).start()

This will repeat the my_func function in intervals every number_of_seconds.

The other option is to instead link your code snippet to a specific action in Blender, by simply putting the call for your function in a well-selected location. I personally recommend this option, if it works in your particular case, since it certainly a more efficient way of handling code.

$\endgroup$
  • 5
    $\begingroup$ You have to be very careful with threading. If you don't terminate the thread before the main script finishes, you'd have tons of problem. So make sure you run threading.join() before exiting the main script. $\endgroup$ – Mike Pan May 29 '13 at 21:29
  • $\begingroup$ As @MikePan notes, threading can be quite dangerous. I'd suggest rather the modal operator (optionally with time events) as a better solution. $\endgroup$ – jesterKing May 29 '13 at 21:38
  • $\begingroup$ @jesterKing I will admit that threading is dangerous, though efficient. I was not aware of the modal operator option, however, I'll have to look into that. Thanks to you and Mike Pan for pointing that out! $\endgroup$ – Gwen May 29 '13 at 21:49
  • 1
    $\begingroup$ @Gwenn. threading in python isn't especially efficient - at least in that it wont make use of multiple cores of a processor. Here is some [documentation][1] regarding threading issues in blender. [1]: blender.org/documentation/blender_python_api_2_67_release/… $\endgroup$ – ideasman42 Jun 1 '13 at 4:54

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.