Filtering

Filtering functionality that aims to mimic the Flow Production Tracking Web UI filter menu.

class filtering.FilterMenu(parent=None, refresh_on_show=True, bg_task_manager=None, dock_widget=None)[source]

Bases: NoCloseOnActionTriggerShotgunMenu

A menu that provides filtering functionality.

How the menu’s filter options are built:

A QSortFilterProxyModel is set for the menu, and the filter menu options reflect the data in the model. The menu’s FilterDefinition processes the model data and constructs a dictionary of data that contains the filter data for each of the model items. The FilterDefintion is then used to populate the menu with the filter QAction/QWidgetAction items.

When the menu is updated/refreshed:

The filter menu is refreshed based on the current model data on showing the menu, to ensure the filter options reflect the current model data accurately. The menu is also refreshed when the filter options are modified, which changes the model data. The menu may also be forced to be refreshed on calling the refresh method with param force as True.

Example usage:

# Create the menu
filter_menu = FilterMenu(parent)

# Set the proxy model that contains the data to be filtered on. This must be called
# before the menu is initialized since the menu requires a model to build the filter
# items (if there is no model, there will be no filter options. The proxy model must
# inherit from the QSortFilterProxyModel class.
#
# If 'connect_signals' is True, the filter model is also expected to have the method
# 'set_filter_items'; the FilterItemProxyModel and FilterItemTreeProxyModel classes
# implement this method, and are designed to work with this FilterMenu class.
#
# If `connect_signals` is not True, the caller will need to connect to the signal
# `filters_changed` signal, which the menu emits, when filters have been modified and
# the proxy model requires updating.
filter_menu.set_filter_model(proxy_model, connect_signals=True)

# Initialize the menu. This will clear the menu and set up the static menu actions (e.g.
# "Clear Filters", "More Filters") and refresh the menu to display available filter
# options (if the model has any data loaded).
filter_menu.initialize_menu()

# Create a QToolButton and set the filter menu on it. The FilterMenuButton class is not
# required, any QToolButton class may be used. The benefit of the FilterMenuButton class
# is that it is designed to work with the FilterMenu specfically, for example, the icon
# will be updated when the menu has active filtering to visually indicate the data is
# filtered.
filter_button = FilterMenuButton(parent)
filter_button.setMenu(filter_menu)

Optional:

# By default, the filter menu options are built from the menu's model data, and the
# model item data role, QtCore.Qt.DisplayRole, is used to extract the data from the model.
# This can be overriden by using `set_filter_roles` and providing a new list of roles
# that will be used to extract the model data.
self._filter_menu.set_filter_roles(
    [
        QtCore.Qt.DisplayRole,
        filter_menu.proxy_model.SOME_ITEM_DATA_ROLE,
        ...
    ]
)

# Call `set_ignore_fields` to ignore certain data when building the filters.
filter_menu.set_ignore_fields(
    [
        "{ROLE}.{FIELD_NAME},  # For non PTR data, fields are of the format "role.field", e.g. "QtCore.Qt.DisplayRole.name"
        "{SG_ENTITY_TYPE}.{FIELD_NAME}",  # For PTR data, fields are of the format "entity_type.field", e.g. "Task.code"
    ]
)

Constructor

Parameters:
  • parent (sgtk.platform.qt.QtWidget) – The parent widget.

  • refresh_on_show (bool) – True will ensure the menu is up to date on show by always refreshing the filters before showing. This will slow performance on menu open, but ensures the data is the most up to date. To only refresh the menu on show on demand, set the refresh_on_show property instead of this parm on init.

  • bg_task_manager (BackgroundTaskManager) – An instance of a Background Task Manager that could be used to perform background task processing.

  • dock_widget (QtGui.QWidget | QtGui.QScrollArea) – Optional widget that the filters can be shown in.

property active_filter

Get the current active filters that are set within the menu.

property has_filtering

Get whether or not the menu has any active filtering.

property more_filters_menu

Get the ‘More Filters’ submenu in the filter menu.

property refresh_on_show

Get or set the property to refresh menu before showing.

property docked

Get or set the docked state of the Filter Menu.

This will always return False if the menu does not have a dock widget. When True, the filters are shown in the dock widget, instead of the menu itself.

property active_preset_filter_name

Get the active preset filter data. :return: The active filter array, or None if no preset filter is active.

property dock_widget

Get the dock widget for the Filter Menu.

static set_widget_action_default_widget_value(widget_action, checked)[source]

Convenience method to set the QWidgetAction’s default widget’s value to the checked value of the QWidgetAction.

This is mainly used by the QWidgetAction’s triggered callback to handle different triggered signal signatures between Qt versions.

is_empty()[source]

Return True if the menu has any filters to show.

get_filters_container()[source]

Get the current parent widget for the filters.

The filters may move between the menu itself and the dock widget, thus the parent widget will change depending on the dock state.

set_preset_filters(preset_filters)[source]

Set the preset filters that can be toggled on/off in the menu. The preset filters are stored as a dictionary where the key is the preset filter name, and the value is the filter data in the format the SG API accepts. :param preset_filters: dict of the preset filters to set.

set_active_preset_filter(preset_filter_name)[source]

Set the active preset filter by name. Pass a None value to clear the active preset filter. :param preset_filter_name: str or None

get_active_preset_filter()[source]

Get the active preset filter data. :return: The active filter array, or None if no preset filter is active.

set_visible_fields(fields)[source]

Set the filters that belong to any of the given fields to be visible.

Parameters:

fields (list<str>) – The filters within the given fields will be shown.

set_accept_fields(fields)[source]

Set the fields to ignore when building the filter definition for the menu.

Parameters:

fields (list<str>) – The fields to ignore

set_ignore_fields(fields)[source]

Set the fields to ignore when building the filter definition for the menu.

Parameters:

fields (list<str>) – The fields to ignore

set_use_fully_qualifiied_name(use)[source]

Set the flag to use the fully qualified name for filters. For example, a filter item representing PTR data will prefix the filter name with the entity type.

Parameters:

use (bool) – True will show fully qualified names for filters.

set_filter_roles(roles)[source]

Set the list of model item data roles that are used to extract data from the model, in order to build the menu filters.

set_tree_level(level)[source]

Set the model tree index level which the filters will be built from. This is to handle tree models that defer loading data, set this to the expected leaf node level.

has_role(roles, check_existence=True)[source]

Check if the filter menu is built using the model item data roles.

Parameters:

check_existence (bool) – True will return a bool indicating if at least one of the roles is in the filter menu’s filter roles, else False. False will return the list of roles that are in the filter menu’s filter roles.

Returns:

If check_existence, then True is returned if any of the roles given are used by the filter menu, else False. If check_existence is False, then from the list of the given roles, only the roles that are used in the filter menu will be returned.

Return type:

bool | List[int]

save_state()[source]

Save the current menu filter state.

Returns:

The current menu filter state that can be used to restore the menu state at a later time.

Return type:

dict

restore_state(state)[source]

Restore the menu with the given state.

If the menu has not been built yet, the state will be restored on first build.

Parameters:

state (dict) – The menu state to restore.

set_filter_model(filter_model, connect_signals=True)[source]

Set the source and proxy models that define the filter menu options.

Parameters:
  • filter_model (sgtk.platform.qt.QSortFilterProxyModel) – The model that is used to build the menu filters.

  • connect_signals (bool) – Whether or not to connect model signals to the appropriate filter menu methods; e.g. model layoutChanged will rebuild the menu.

refresh(force=False)[source]

Refresh the filter menu.

This operation will rebuild the underlying filter definition that the filter menu is built from. The filter definition is built based on the current filter model data.

The filter menu widgets will be cleared and rebuilt. The current menu state will be saved before rebuild, and restored once the refresh operation is complete.

Emits menu_refreshed signal once refresh is done.

update_filters(filter_group_ids=None)[source]

Update only the active/visible filters in the menu.

clear_menu()[source]

Clear any active filters that are set in the menu. Clear the internal menu data and remove all items from the menu.

clear_filters(filter_group_ids=None, clear_active_preset_filter=False)[source]

Clear any active filters that are set in the menu.

undock_filters(force=False)[source]

Show filters in the menu.

dock_filters(force=False)[source]

Show filters in the dock widget.

get_current_filters(exclude_choices_from_fields=None)[source]

Get the current filters that are active in the menu.

The menu filtering is built by:
  1. Within a filter field, all choice filters are grouped with OR, to create a group filter item

  2. All filter field group items are then combined with AND to get the final filter item

If the exclude_choices_from_fields is provided, this will not add any choice filters from the listed fields. Note that the search filter for these fields will still be included. This is used by the filter definition to get filter choice value counts.

Parameters:

exclude_choices_from_fields (List[str]) – The list of fields to exclude when collecting the currently active filtering from the menu.

Returns:

A filter item representing the current filtering in the menu.

Return type:

List[FilterItem]

initialize_menu()[source]

Initialize the filter menu.

This method no longer needs to be called to initialize the menu since refresh will take care of re-initializing. This method now just calls refresh for backward compatibility.

class filtering.FilterMenuButton(parent=None, text=None, icon=None)[source]

Bases: object

A QToolButton to be used with the FilterMenu class.

Constructor.

Parameters:
  • parent (sgtk.platform.qt.QtGui.QWidget) – The parent widget.

  • text (str) – The text displayed on the button.

  • icon (sgtk.platform.qt.QtGui.QIcon) – The button icon.

setMenu(menu)[source]

Override the base QToolButton method.

Enforce the menu to be of type FilterMenu. Connect the menu’s filters changed signal to update the menu button accordingly.

setEnabled(enabled)[source]

Override the base QToolButton method to ensure the check state is restored.

update_button_checked()[source]

Callback triggered when the menu filters have changed. Update the button’s checked state based on the menu’s current filtering.

set_enabled(enabled)[source]

Update the button enabled state.

Parameters:

enabled (bool) – True will turn on the button (enable), else False will turn off (disable).

class filtering.FilterItem(filter_id, filter_type, filter_op, filter_value=None, filter_role=None, data_func=None)[source]

Bases: object

Class object to encapsulate all the necessary data to filter model index data.

A FilterItem properties:

filter type:

This determines how the incoming data is processed and filtered, and is most likely determined based on the filter value data type. See supported filter types in FilterType enum class.

filter_op:

This determines the operation that is applied on filtering the data. See supported filter operations in FilterOp enum class.

filter_value:

This is the value that incoming data is compared against, when filtering. For group filter items, this will be the list of filter items the group uses for filtering.

filters:

This is a convenience property to access the filter items for a group filter.

filter_role:

The model item data role that will be used to extract the data from incoming indexes to be filtered. This is optional, but if not defined, then a data_func must be defined.

data_func:

This is a function that is used to extract the data from incoming indexes to be filterd. This is option, but if not defined, then a filter_role must be defined.

To filter an index by a FilterItem, call the accepts method, e.g.:

filter_item.accepts(index)

To filter an index by a group of FilterItems, the accept method can be used the same as non-group filters, or the classmethod FilterItem.do_filter(index, filters, filter_op) may be used. When filtering using groups of FilterItems, the individual results of the FilterItem accept tests are AND’ed or OR’ed together based on the group. The filter groups can be nested by including a group filter in the group filters list.

Constructor.

Validate the data on creating the object.

Parameters:
  • filter_type (FilterType) – The data type for the filter

  • filter_op (FilterOp) – The operation the filter will apply.

  • filter_role (sgtk.platform.qt.QtCore.Qt.ItemDataRole) – An item data role to extract the index data to filter based on (optional).

  • data_func – A function that can be called to extract the index data to filter based on (optional). NOTE: if a filter_role is defined, this will have no effect.

  • filter_value (The data type for this filter) – The value the item’s data will be filtered by (optional). This value may be set later (dynamically), if not known at time of init.

  • filters (list<FilterItem>) – A list of FilterItem objects (optional). This is used for group filters; this list of filter items are the group of filters to apply to the data.

class FilterOp[source]

Bases: object

Enum class for filter operations.

class FilterType[source]

Bases: object

Enum class for filter types.

property id

Get the id for this FilterItem.

property filter_type

Get or set the filter type.

property filter_op

Get or set the filter operation.

property filter_value

Get or set the value for the filter that incoming data will be compared against to check acceptance.

property filters

Get or set the list of filter items for this group filter. This is a convenience property for group filter items, and hides the internal implementation details of storing the filters in the filter items filter_value.

property filter_role

Get or set the model item data role used to extract data from incoming indexes to be filtered.

property data_func

Get or set the function used to extract data from incoming indexes to be filtered.

classmethod create(filter_id, data)[source]

Convenience factory classmethod to create a new FilterItem object from the provided data.

Parameters:

data (dict) – The data to create the FilterItem object from.

Returns:

The created FilterItem object

Return type:

FilterItem

classmethod create_group(op, group_filters=None, group_id=None)[source]

Convenience factory method to create a new FilterItem object that is a group.

Parameters:
  • op (FilterOp) – The group operation to set for this filter item.

  • group_filters (list<FilterItem>) – The list of FilterItems for this group filter (optional).

  • group_id (str) – The identifier for the group (optional). If none given, the filter item will have id “FilterType.FilterOp”.

Returns:

The created FilterItem object whose type is FilterType.GROUP

Return type:

FilterItem

classmethod get_data_type(data)[source]

Return the FilterItem type for the given data.

Parameters:

data (any) – The data to get the type for.

Returns:

The FilterItem type of the data. None is returned for invalid data.

Return type:

FilterType

classmethod default_op_for_type(filter_type)[source]

Return the default operation for the given filter data type.

Parameters:

filter_type (str) – One of the defined FilterItem types; e.g. FilterItem.FilterType.{name}.

Returns:

The default operation to apply to the given filter type.

Return type:

str, one of the FilterItem operations defined in the class; e.g. FilterItem.FilterOp.{name}.

classmethod is_group_op(op)[source]

Return True if the filter item operation is valid.

Parameters:

op (FilterOp) – The operation to check.

Returns:

True if the op is a group operation, else False.

Return type:

bool

classmethod do_filter(index, filter_items, op='and')[source]

Return True if the index is accepted by the list of filter items.

Parameters:
  • index (sgtk.platform.qt.QtCore.QModelIndex) – The index to check acceptance on.

  • filter_items (list<FilterItem>) – The list of filter items used to check acceptance.

  • op (FilterOp) – The filter operation to apply with checking acceptance.

Returns:

True if accepted, else False.

Return type:

bool

classmethod map_from_sg_data_type(sg_data_type)[source]

Map the PTR data type to a valid filter type.

Parameters:

sg_data_type (str) – The PTR data type.

Returns:

The corresponding filter type for the PTR data type.

Return type:

str

static get_datetime_bucket(dt)[source]

This attempts to get the datetime bucket for the given datetime passed. Datetime buckets follow the same logic as the ShotGrid Web UI.

NOTE should we move this to shotgun_globals.date_time module?

Parameters:

dt (str | float | datetime.datetime) – The datetime value to process

Returns:

The datetime bucket that this datetime value falls into.

Return type:

str

is_group()[source]
Returns:

True if this filter item is a group, else False.

Return type:

bool

get_index_data(index)[source]

Return the index’s data based on the filter item. The index data will be first attempted to be retrieved from the index’s data method, using the filter role. If no role is defined, the data_func will be called to extract the data (if such a function is defined).

A filter_role or data_func must be defined to reteieve the index data.

Parameters:

index (sgtk.platform.qt.QtCore.QModelIndex) – The index to get the data from

Returns:

The index data

Return type:

any

accepts(index)[source]

Return True if this filter item accepts the given index.

Parameters:

index (sgtk.platform.qt.QtCore.QModelIndex) – The index that holds the data to filter on.

Returns:

True if the filter accepts the index, else False.

Return type:

bool

is_bool_valid(value)[source]

Filter the incoming boolean value.

Parameters:

value (bool) – The value to filter.

Returns:

True if the filter accepts the value, else False.

Return type:

bool

is_str_valid(value)[source]

Filter the incoming string value.

Parameters:

value (str) – The value to filter.

Returns:

True if the filter accepts the value, else False.

Return type:

bool

is_number_valid(value)[source]

Filter the incoming number value.

Parameters:

value (int | float | ...) – The value to filter.

Returns:

True if the filter accepts the value, else False.

Return type:

bool

is_datetime_valid(value)[source]

Filter the incoming datetime value.

TODO support operations like greater/less than and between.

Parameters:

value (str | datetime.datetime) – The value to filter.

Returns:

True if the filter accepts the value, else False.

Return type:

bool

is_list_valid(values_list)[source]

Filter the incoming list value.

Parameters:

value (list) – The values list to filter by.

Returns:

True if the filter accepts the values list, else False.

Return type:

bool

is_dict_valid(value)[source]

Filter the incoming dictionary value.

Parameters:

value (list) – The values list to filter by.

Returns:

True if the filter accepts the values list, else False.

Return type:

bool

Check if the filter item matches the search value.

Parameters:

search (any) – The search value.

Returns:

True if the filter item’s value matches the search value, else False.

set_filter_value(value)[source]

Set the filter item’s filter value.

Parameters:

value (any) – The value to set.

Returns:

True if the filter item’s value was updated, else False. If the value is the same as the current filter value, False will be returned.

Return type:

bool

class filtering.FilterItemProxyModel(*args, **kwargs)[source]

Bases: QSortFilterProxyModel

A filter proxy model that filters the source model data using a list of FilterItem objects.

Constructor.

property filter_group_op

Get or set the operation applied to the list of filter items in this model upon filtering.

property filter_items

Get or set the list of FilterItem objects used to filter the model data.

set_filter_items(items, emit_signal=True)[source]

Set the list of FilterItem objects used to filter the model data. If emit_signal, then also invalidate the filter to immediately trigger re-filtering the model data.

filterAcceptsRow(src_row, src_parent_idx)[source]

Overrides the base QSortFilterProxyModel implementation.

Return True if the the row is accepted by the filter items. The row is accepted if the data is accepted by the list of FilterItems OR’ed or AND’ed together, depending on the group operation.

Parameters:
  • src_row (int) – The row in the source model to filter.

  • src_parent_idx (sgtk.platform.qt.QModelIndex) – The parent index of the source model’s row to filter.

Returns:

True if the row is accepted, else False.

Return type:

bool

class filtering.FilterItemTreeProxyModel(*args, **kwargs)[source]

Bases: object

A filter proxy model that filters the source tree model data using a list of FilterItem objects. This provides similar functionality as the FilterItemFilterProxyModel, except for models that need to inherit from the HierarchicalfilteringProxyModel.

Constructor

property filter_group_op

Get or set the operation applied to the list of filter items in this model upon filtering.

property filter_items

Get or set the filter items used to filter the model data.

set_filter_items(items, emit_signal=True)[source]

Set the list of FilterItem objects used to filter the model data. If emit_signal, then also invalidate the filter to immediately trigger re-filtering the model data.