Difference between revisions of "IC Python API:Stopwatch"

From Reallusion Wiki!
Jump to: navigation, search
(Created page with "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 f...")
(No difference)

Revision as of 20:12, 13 August 2019

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 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.

stop_watch = {}  # Globals


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):
        RLPy.RPyTimerCallback.__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"])
        widget.lcdNumber.display(time.strftime('%M:%S:%f')[:-4])
        widget.dial.setValue(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):
        RLPy.RDialogCallback.__init__(self)

    def OnDialogHide(self):
        global stop_watch

        stop_watch["timer"].UnregisterPyTimerCallback()
        del stop_watch


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"]:
        widget.toggle.setText("Stop")
        stop_watch["timer"].Start()
    else:
        widget.toggle.setText("Start")
        stop_watch["timer"].Stop()


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
    widget.dial.setValue(0)
    widget.lcdNumber.display("00:00:00")
    stop_watch["activated"] = True
    toggle()