Difference between revisions of "IC Python API:Table View"
Chuck (RL) (Talk | contribs) m |
Chuck (RL) (Talk | contribs) m (→Refresh Function) |
||
Line 43: | Line 43: | ||
Notice how the resize policy is set by adjusting the '''header''' attribute. | Notice how the resize policy is set by adjusting the '''header''' attribute. | ||
− | == Refresh Function == | + | === Refresh Function === |
[[File:Ic_python_api_lights_table_03.png|frame]] | [[File:Ic_python_api_lights_table_03.png|frame]] |
Revision as of 00:37, 16 December 2019
- Main article: RL Python Samples.
If your assets are part of a hierarchical structure, then a QT tree widget would be more suitable.
This article will go over the creation of a table widget for listing all the standard lights in the scene; their name, active state, multiplier, and color attributes. To top it off, we will add a refresh button to the window to update the light list to the current state of the scene.
Necessary Modules
Besides the fundamental Reallusion Python module, we'll also need Pyside2 to build the user interface. But we don't need the entire Pyside2 module for this simple example, so I'll just import QtWidgets for building the user interface and wrapInstance to bind the iClone dialog window to the Pyside2 interface.
import RLPy
from PySide2 import QtWidgets
from PySide2.shiboken2 import wrapInstance
Light Table Widget
In order to create a table widget we must first create the widget as a class that inherits from the QtWidgets.QtableWidget class. This will give us a shell of a table widget to work with, i.e. to populate.
class LightTableWidget(QtWidgets.QTableWidget):
def __init__(self):
super().__init__()
labels = ["Name", "Active", "Multiplier", "Color (RGB)"]
self.setColumnCount(len(labels))
self.setHorizontalHeaderLabels(labels)
# Adjust row resize policy
header = self.horizontalHeader()
header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)
Notice how the resize policy is set by adjusting the header attribute.
Refresh Function
In order to populate the scene lights table, we have to add a refresh method to search the scene for all of the lights and add them one by one to the table widget. This method belongs in the same class we used to inherit from the QtWidgets.QTableWidget because of this we can rely on the handy self keyword to refer to the instance of the class (after its creation).
self.refresh()
def refresh(self):
# Clear the table widget
self.setRowCount(0)
# Grab all props in the scene
all_lights = RLPy.RScene.FindObjects(RLPy.EObjectType_Light)
# Add an entry into the combo-box for every prop found
for i in range(len(all_lights)):
row_count = self.rowCount()
self.setRowCount(row_count + 1)
# Create a object name item
item_object = QtWidgets.QTableWidgetItem()
item_object.setText(all_lights[i].GetName())
self.setItem(row_count, 0, item_object)
# Create a active toggle item
active_object = QtWidgets.QTableWidgetItem()
active_object.setText(str(all_lights[i].GetActive()))
self.setItem(row_count, 1, active_object)
# Create multiplier item
multiplier_object = QtWidgets.QTableWidgetItem()
multiplier_object.setText(str(round(all_lights[i].GetMultiplier(), 4)))
self.setItem(row_count, 2, multiplier_object)
# Create a color item
color_object = QtWidgets.QTableWidgetItem()
color = all_lights[i].GetColor()
color_value = "{} - {} - {}".format(color.Red(), color.Green(), color.Blue())
color_object.setText(color_value)
self.setItem(row_count, 3, color_object)
Notice that we call refresh command in the initialization phase. Unlike normal python declaration order, methods and call to methods inside classes don't have to follow a specific order due to the use of self. refresh method from outside of the class after its declaration which would look like the following:
table_widget = LightTableWidget()
table_widget.refresh()
Dialog Window Boilerplate
In order for us to show the scene lights table list we must first create a window, declare an instance of our custom table class, and attach the said table to the window layout.
# Create a dialog window
dialog = RLPy.RUi.CreateRDialog()
dialog.SetWindowTitle("Scene Lights")
# Create Pyside layout for RDialog
qt_dialog = wrapInstance(int(dialog.GetWindow()), QtWidgets.QDialog)
main_widget = QtWidgets.QWidget()
qt_dialog.setFixedWidth(350)
# Create a Light Table widget
table_widget = LightTableWidget()
qt_dialog.layout().addWidget(table_widget)
We can also add a handy refresh button that simply calls the method declared in the custom table class. Finally, we will need to show the window.
# Add a refresh button
refresh_button = QtWidgets.QPushButton()
refresh_button.setFixedHeight(24)
refresh_button.setText("Refresh List")
refresh_button.clicked.connect(lambda: table_widget.refresh())
qt_dialog.layout().addWidget(refresh_button)
dialog.Show()
Notice the use of lambda which is a handy way to declare an anonymous function.
Everything Put Together
You can copy and paste the following code into a PY file and load it into iClone via Script > Load Python.
import RLPy
from PySide2 import QtWidgets
from PySide2.shiboken2 import wrapInstance
class LightTableWidget(QtWidgets.QTableWidget):
def __init__(self):
super().__init__()
labels = ["Name", "Active", "Multiplier", "Color (RGB)"]
self.setColumnCount(len(labels))
self.setHorizontalHeaderLabels(labels)
# Adjust row resize policy
header = self.horizontalHeader()
header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)
self.refresh()
def refresh(self):
# Clear the table widget
self.setRowCount(0)
# Grab all props in the scene
all_lights = RLPy.RScene.FindObjects(RLPy.EObjectType_Light)
# Add an entry into the combo-box for every prop found
for i in range(len(all_lights)):
row_count = self.rowCount()
self.setRowCount(row_count + 1)
# Create a object name item
item_object = QtWidgets.QTableWidgetItem()
item_object.setText(all_lights[i].GetName())
self.setItem(row_count, 0, item_object)
# Create a active toggle item
active_object = QtWidgets.QTableWidgetItem()
active_object.setText(str(all_lights[i].GetActive()))
self.setItem(row_count, 1, active_object)
# Create multiplier item
multiplier_object = QtWidgets.QTableWidgetItem()
multiplier_object.setText(str(round(all_lights[i].GetMultiplier(), 4)))
self.setItem(row_count, 2, multiplier_object)
# Create a color item
color_object = QtWidgets.QTableWidgetItem()
color = all_lights[i].GetColor()
color_value = "{} - {} - {}".format(color.Red(), color.Green(), color.Blue())
color_object.setText(color_value)
self.setItem(row_count, 3, color_object)
# Create a dialog window
dialog = RLPy.RUi.CreateRDialog()
dialog.SetWindowTitle("Scene Lights")
# Create Pyside layout for RDialog
qt_dialog = wrapInstance(int(dialog.GetWindow()), QtWidgets.QDialog)
main_widget = QtWidgets.QWidget()
qt_dialog.setFixedWidth(350)
# Create a Light Table widget
table_widget = LightTableWidget()
qt_dialog.layout().addWidget(table_widget)
# Add a refresh button
refresh_button = QtWidgets.QPushButton()
refresh_button.setFixedHeight(24)
refresh_button.setText("Refresh List")
refresh_button.clicked.connect(lambda: table_widget.refresh())
qt_dialog.layout().addWidget(refresh_button)
dialog.Show()
APIs Used
You can research the following references for the APIs deployed in this code.