IC Python API:Loading JSON

From Reallusion Wiki!
Jump to: navigation, search
Main article: RL Python Samples.

This article will go over the handling of Json formatted data for iClone. This is done by loading an external Json file and mining its data for display. In this case, we'll making a catalog for a handful of books about coding in Javascript.

Json File

Json is a strict format that is easy to read and understand. You should always wrap the data in a grand object with a key and value entry and never in an array. For example, inside the master Json object, we have a "books" entry that contains an array of objects that describe individual books.

{
    "books": [{
            "isbn": "9781593275846",
            "title": "Eloquent JavaScript, Second Edition",
            "subtitle": "A Modern Introduction to Programming",
            "author": "Marijn Haverbeke",
            "published": "2014-12-14T00:00:00.000Z",
            "publisher": "No Starch Press",
            "pages": 472,
            "description": "JavaScript lies at the heart of almost...",
            "website": "http://eloquentjavascript.net/"
        }]
}
[Expand]
You can copy and paste the following Json data into Book_Catalog.py and place it in the same directory of the Python script file.

Necessary Modules

import os
import json
import RLPy
from PySide2 import QtWidgets
from PySide2.shiboken2 import wrapInstance
from PySide2.QtCore import *

We'll need RLPy to access iClone's Python API and Pyside2 related modules to create a functional interface.

os

The os module provides a portable way of using operating system dependent functionality. For more information, see os.html.

json

JSON (JavaScript Object Notation), specified by RFC 7159 and by ECMA-404, is a lightweight data interchange format inspired by JavaScript object literal syntax (although it is not a strict subset of JavaScript). For more information, see the Python json documentation.

Pyside2

PySide2 is the official Python module from the Qt for Python project, which provides access to the complete Qt 5.12+ framework. For more information, see the Pyside2 documentation.

Initializing the UI

# Create an iClone Dock Widget
dock_window = RLPy.RUi.CreateRDockWidget()
dock_window.SetWindowTitle("Book Catalog")

# Create Pyside layout for RDockWidget
dock = wrapInstance(int(dock_window.GetWindow()), QtWidgets.QDockWidget)

# Configure the dock window
main_widget = QtWidgets.QWidget()
dock.setWidget(main_widget)
dock.setFixedSize(350, 750)
dock.setStyleSheet("QGroupBox  {color: #a2ec13;} QLabel {color: #6dbfff;}")

main_layout = QtWidgets.QVBoxLayout()
main_widget.setLayout(main_layout)

Loading Books

To load a different book, we'll need to clear the original widgets and fill it up again with widgets containing the pertinent information. The code below does exactly this. An alternative way is to just create all of the widgets at once and change their values at run-time.

def change_book(index):
    info = books_data["books"][index]

    # Clear the entire layout except for the book selection dropdown
    while main_layout.count() - 1:
        child = main_layout.takeAt(1)
        if child.widget():
            child.widget().deleteLater()

    # Fill the layout with book information
    for key, value in info.items():
        label = QtWidgets.QLabel(
            text=str(value), wordWrap=True, textInteractionFlags=Qt.TextSelectableByMouse)
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(label)
        group_box = QtWidgets.QGroupBox(title=str(key).capitalize())
        group_box.setLayout(layout)
        main_layout.addWidget(group_box)

    main_layout.addStretch()

Now that the we have the function for changing the focus to another book, we'll need to bind it to a book selection drop-down menu.

book_dropdown = QtWidgets.QComboBox()
book_dropdown.currentIndexChanged.connect(lambda x: change_book(x))

main_layout.addWidget(book_dropdown)

Retrieving Json Data

The final step is to retrieve the data residing in the Book_Catalog.json file and show the window.

# Read the Book Catalog Json file
local_path = os.path.dirname(os.path.realpath(__file__))
json_file_path = os.path.join(local_path, "Book_Catalog.json")

with open(json_file_path, "r", encoding="utf-8") as json_file:
    books_data = json.load(json_file)
    for index, entry in enumerate(books_data["books"]):
        book_dropdown.addItem(f'({str(index)}) {entry["title"]}')

dock_window.Show()

Everything Put Together

You can copy and paste the following code into a PY file and load it into iClone via Script > Load Python. Make sure to download the example JSON file mentioned under the Json File section and place it in the same location as the script file.

Ic python api book catalog 01.png
import os
import json
import RLPy
from PySide2 import QtWidgets
from PySide2.shiboken2 import wrapInstance
from PySide2.QtCore import *

# Create an iClone Dock Widget
dock_window = RLPy.RUi.CreateRDockWidget()
dock_window.SetWindowTitle("Book Catalog")

# Create Pyside layout for RDockWidget
dock = wrapInstance(int(dock_window.GetWindow()), QtWidgets.QDockWidget)

# Configure the dock window
main_widget = QtWidgets.QWidget()
dock.setWidget(main_widget)
dock.setFixedSize(350, 750)
dock.setStyleSheet("QGroupBox  {color: #a2ec13;} QLabel {color: #6dbfff;}")

main_layout = QtWidgets.QVBoxLayout()
main_widget.setLayout(main_layout)


def change_book(index):
    info = books_data["books"][index]

    # Clear the entire layout except for the book selection dropdown
    while main_layout.count() - 1:
        child = main_layout.takeAt(1)
        if child.widget():
            child.widget().deleteLater()

    # Fill the layout with book information
    for key, value in info.items():
        label = QtWidgets.QLabel(
            text=str(value), wordWrap=True, textInteractionFlags=Qt.TextSelectableByMouse)
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(label)
        group_box = QtWidgets.QGroupBox(title=str(key).capitalize())
        group_box.setLayout(layout)
        main_layout.addWidget(group_box)

    main_layout.addStretch()


book_dropdown = QtWidgets.QComboBox()
book_dropdown.currentIndexChanged.connect(lambda x: change_book(x))

main_layout.addWidget(book_dropdown)

books_data = {}

# Read the Book Catalog Json file
local_path = os.path.dirname(os.path.realpath(__file__))
json_file_path = os.path.join(local_path, "Book_Catalog.json")

with open(json_file_path, "r", encoding="utf-8") as json_file:
    books_data = json.load(json_file)
    for index, entry in enumerate(books_data["books"]):
        book_dropdown.addItem(f'({str(index)}) {entry["title"]}')

dock_window.Show()

APIs Used

You can research the following references for the APIs deployed in this code.