Difference between revisions of "IC Python API:Stopwatch"

From Reallusion Wiki!
Jump to: navigation, search
Line 1: Line 1:
{{Parent|IC_Python_API:RL_Python_Samples|RL Python Samples}}
This article will demonstrate the usage of the timer class and handling the timer callback events by creating a stopwatch inside iClone.
This article will demonstrate the usage of the timer class and handling the timer callback events by creating a stopwatch inside iClone.

Revision as of 22:39, 13 August 2019

Main article: RL Python Samples.

This article will demonstrate the usage of the timer class and handling the timer callback events by creating a stopwatch inside iClone.

Required Modules

Besides the fundamental Reallusion Python module, we'll also need Pyside2 to build the user interface, os to read a qt UI file, and datetime to handle the time format.

import RLPy
import os
import datetime
from PySide2 import *
from PySide2.shiboken2 import wrapInstance

Timer Callback Class

In order to create a timer callback event, we have to inherit from the RLPy.RPyTimerCallback class and modify it -specifically the Timeout function that triggers on each interval.

class TimerCallback(RLPy.RPyTimerCallback):
    def __init__(self):

    def Timeout(self):
        global stop_watch
        if stop_watch["milliseconds"] > 5949999:  # Restart the timer at 99:99:99 mark
            stop_watch["milliseconds"] = 0
        stop_watch["milliseconds"] += 10
        time = datetime.datetime.min + datetime.timedelta(milliseconds=stop_watch["milliseconds"])

Dialog Event Callback

A timer is a very powerful feature in iClone scripting but is easily prone to abuse due to its tendency to proliferate the session with background calculations that are invisible to the user once initiated. Therefore, it is highly recommended to also handle the events clean up process with a interface dependent callback, specifically in the form of a dialog event callback. By doing so, we tie the timer events that were fired off with the presence of a user interface, and once that interface ceases to exist (for instance, when closed) then the timer can be recalled and all related global variables can be sanitized.

class DialogEventCallback(RLPy.RDialogCallback):
    def __init__(self):

    def OnDialogHide(self):
        global stop_watch

        del stop_watch

Timer Event Globals

All events in iClone must be declared as global variables. This means that event variables lie outside the scope of class and functions and must be so in order for iClone to properly handle callback requests. There is no one size fits all for this scenario, some people prefer to create separate global variables, but for this simple exercise, we'll just create a dictionary that'll house all of the global variables needed for this script and populate it.

# Global variables
stop_watch = {}
stop_watch["activated"] = False
stop_watch["milliseconds"] = 0
stop_watch["timer"] = RLPy.RPyTimer()
stop_watch["callback"] = TimerCallback()

Stopwatch Start/Stop Button

The stopwatch start/stop button is simply a toggle function that inverts the state of the watch from running to stopped and vice versa.

def toggle():
    global stop_watch

    stop_watch["activated"] = not stop_watch["activated"]

    if stop_watch["activated"]:

Stopwatch Reset Button

As a fancy feature, we'll add the function for stopping the watch and resetting the counter back to 00:00:00.

def reset():
    global stop_watch

    stop_watch["milliseconds"] = 0
    stop_watch["activated"] = True

Creating the Interface

Let's load the configured QT UI file.

# Create the dialog window in iClone
window = RLPy.RUi.CreateRDialog()
window.SetWindowTitle("Stop Watch")

# Empower the window with Python QT functionalities
dialog = wrapInstance(int(window.GetWindow()), QtWidgets.QDialog)

# Read the QT UI file from location and deploy as widget
ui = QtCore.QFile(os.path.dirname(__file__) + "/Stop_Watch.ui")
widget = QtUiTools.QUiLoader().load(ui)

# Configure and connect functions to the stopwatch widget

# Dialog event callback
dialogCallback = DialogEventCallback()