Skip to content

How a Component Works

Brianna edited this page Jul 28, 2017 · 1 revision

How a Component Works

Definition

All components must inherit from the Component base class, which is a type of QObject. The class must have the following attributes (as class variables):

  1. name

  2. version (a string such as '1.0.0')

The major version is used to determine preset compatibility, i.e., presets created for version 1.0.0 will work with 1.1.2 but not 2.0.0.

By default, the module filename is used to find the component's .ui file (module.py uses module.ui). An optional ui attribute may be defined for a custom .ui filename if necessary.

When created

  1. The component's widget() method is called to create the component's QtWidget (saved as self.page).

  2. Any simple widgets within the page (e.g., lineedits, checkboxes, spinboxes) are automatically connected to the component's update() method.

  3. To save the values of these widgets as attributes, this magical method must be used within the widget()definition: trackWidgets({'attribute_name': self.page.widget})

  4. Immediately after creation, update() is called.

  5. If the program is in commandline mode, command() will be called next to process an argument. If the argument isn't valid, the subclass should call super().command(*args) to let the base class trigger commandHelp().

While idle

  1. The update() method could be called any number of times, possibly as the user changes configuration rapidly. Any tracked widgets (defined by trackWidgets({})) will have their values assigned to the corresponding attribute.

  2. savePreset() and loadPreset() could be called at any time. The first may be called far more often for creating autosaves. Both methods will automatically make use of tracked widgets.

  3. previewRender() must return a Pillow image of the exact correct frame size (use toolkit.frame functions).

While exporting a video

  1. preFrameRender() is called to give the components attributes such as completeAudioArray which contains raw PCM data the component could use for a visualization.

  2. properties() is checked next to see what properties the component has. It must return a list of strings from this pool: static, audio, error. Each property's method is called if it exists in this list.

  3. static has no further options, the presence of the property simply indicates that the component is not animated and only needs its frameRender() method to be called once.

  4. audio() must return a tuple of (filename, {ffmpeg_parameters}). The filename is used as an input file for ffmpeg, and the ffmpeg parameters are used to define a series of audio filters to be applied to this input file.

  5. error() may be undefined or return a string for a simple error message, or a tuple with two strings for more detail.

  6. frameRender(int frameNumber) is called as many times as needed to construct the video. This method must return a Pillow image of the exact correct size (use toolkit.frame functions).

  7. postFrameRender() is called at the end of the export, whether it completes successfully or not, in case the component needs to do any cleanup.