def __init__(self, parent=None): """ Initialize the demo widget. """ # call the base class init super(NavigationDemo, self).__init__(parent) # get a handle on the current toolkit bundle (the demo app). self._app = sgtk.platform.current_bundle() # create a background task manager for the widget to use self._bg_task_manager = task_manager.BackgroundTaskManager(self) # keep track of when we're navigating self._navigating = False # setup the designer UI self.ui = Ui_NavigationWidgetDemoUI() self.ui.setupUi(self) project = self._app.get_demo_entity("Project") if not project: raise Exception("Could not find suitable project for this demo!") # create a hierarchy model to display data an attach it to the view self._hierarchy_model = shotgun_model.SimpleShotgunHierarchyModel( self, bg_task_manager=self._bg_task_manager ) # create a proxy model to sort the hierarchy self._hierarchy_proxy_model = QtGui.QSortFilterProxyModel(self) self._hierarchy_proxy_model.setDynamicSortFilter(True) # set the proxy model's source to the hierarchy model self._hierarchy_proxy_model.setSourceModel(self._hierarchy_model) # set the proxy model as the data source for the view self.ui.tree_view.setModel(self._hierarchy_proxy_model) self.ui.tree_view.header().hide() self.ui.tree_view.setSortingEnabled(True) self.ui.tree_view.sortByColumn(0, QtCore.Qt.AscendingOrder) # build a hierarchy for the current project targeting entities linked # to the "entity" field on "Version" entities self._hierarchy_model.load_data("Version.entity") # ---- connect some signals # handle navigation widget clicks self.ui.nav_widget.home_clicked.connect(self._on_home_clicked) self.ui.nav_widget.navigate.connect(self._on_navigate) # now handle hierarchy selection selection_model = self.ui.tree_view.selectionModel() selection_model.selectionChanged.connect( self._on_hierarchy_selection_changed )
def __init__(self, parent=None): """ Return the ``QtGui.QWidget`` instance for this demo. """ super(ShotgunEntityModelDemo, self).__init__(parent) # see if we can determine the current project. if we can, only show the # assets for this project. self._app = sgtk.platform.current_bundle() if self._app.context.project: filters = ["project", "is", self._app.context.project] else: filters = [] # construct the view and set the model self._entity_view = QtGui.QTreeView() self._entity_view.setIndentation(16) self._entity_view.setUniformRowHeights(True) self._entity_view.setSortingEnabled(True) self._entity_view.sortByColumn(0, QtCore.Qt.AscendingOrder) # construct an entity model then load some data. self._entity_model = shotgun_model.ShotgunEntityModel( "Asset", # entity type [filters], # filters ["project.Project.name", "sg_asset_type", "code"], # hierarchy ["description", "id", "project", "sg_asset_type"], # fields self, ) # refresh the data to ensure it is up-to-date self._entity_model.async_refresh() # create a proxy model to sort the model self._entity_proxy_model = QtGui.QSortFilterProxyModel(self) self._entity_proxy_model.setDynamicSortFilter(True) # set the proxy model's source to the entity model self._entity_proxy_model.setSourceModel(self._entity_model) # set the proxy model as the data source for the view self._entity_view.setModel(self._entity_proxy_model) info_lbl = QtGui.QLabel( "This demo shows how to use the <tt>ShotgunEntityModel</tt> to " "display a hierarchy of <b>Asset</b> entities." ) layout = QtGui.QVBoxLayout(self) layout.addWidget(info_lbl) layout.addWidget(self._entity_view)
def _populate_ui(self): """ Populate the UI with the data. """ # construct a hierarchy model then load some data. # "Version.entity" seed means build a hierarchy that leads to # entities that are linked via the Version.entity field. # by default the model will be built for the current project. # if no project can be determined from the current context, # the model will be built with top-level items for each project. self._hierarchy_model = shotgun_model.SimpleShotgunHierarchyModel( self, bg_task_manager=self._bg_task_manager) self._hierarchy_model.load_data("Version.entity") # create a proxy model to sort the hierarchy self._hierarchy_proxy_model = QtGui.QSortFilterProxyModel(self) self._hierarchy_proxy_model.setDynamicSortFilter(True) # set the proxy model's source to the hierarchy model self._hierarchy_proxy_model.setSourceModel(self._hierarchy_model) # set the proxy model as the data source for the view self._hierarchy_view.setModel(self._hierarchy_proxy_model) # create a simple shotgun model for querying the versions self._version_model = shotgun_model.SimpleShotgunModel( self, bg_task_manager=self._bg_task_manager) # --- connect some signals # as hierarchy view selection changes, query versions selection_model = self._hierarchy_view.selectionModel() selection_model.selectionChanged.connect( self._on_hierarchy_selection_changed) # show the overlay on the versions as they're being queried self._version_model.data_refreshing.connect( lambda: self._overlay_widget.start_spin()) self._version_model.data_refreshed.connect(self._on_data_refreshed)
def __init__(self, parent=None): """ Constructor """ # first, call the base class and let it do its thing. QtGui.QWidget.__init__(self, parent) # most of the useful accessors are available through the Application class instance # it is often handy to keep a reference to this. You can get it via the following method: self._app = sgtk.platform.current_bundle() self._action_manager = ActionManager(self) self._action_manager.refresh_request.connect(self.setup_ui) # create a background task manager self._task_manager = task_manager.BackgroundTaskManager( self, start_processing=True, max_threads=2) # register the data fetcher with the global schema manager shotgun_globals.register_bg_task_manager(self._task_manager) # now load in the UI that was created in the UI designer self.ui = Ui_Dialog() self.ui.setupUi(self) # create a note updater to run operations on notes in the db self._note_updater = NoteUpdater(self._task_manager, self) # flag to keep track of when we are navigating self._navigating = False # hook up a data retriever with all objects needing to talk to sg self.ui.search_input.set_bg_task_manager(self._task_manager) self.ui.note_reply_widget.set_bg_task_manager(self._task_manager) self.ui.entity_activity_stream.set_bg_task_manager(self._task_manager) self.ui.version_activity_stream.set_bg_task_manager(self._task_manager) # set up action menu. parent it to the action button to prevent cases # where it shows up elsewhere on screen (as in Houdini) self._menu = shotgun_menus.ShotgunMenu(self.ui.action_button) self.ui.action_button.setMenu(self._menu) # this forces the menu to be right aligned with the button. This is # preferable since many DCCs show the embed panel on the far right. In # houdini at least, before forcing this layout direction, the menu was # showing up partially offscreen. self.ui.action_button.setLayoutDirection(QtCore.Qt.RightToLeft) # our current object we are currently displaying self._current_location = None # track the history self._history_items = [] self._history_index = 0 # overlay to show messages self._overlay = overlay_module.ShotgunOverlayWidget(self) # figure out which type of publish this toolkit project is using self._publish_entity_type = sgtk.util.get_published_file_entity_type( self._app.sgtk) # create a settings manager where we can pull and push prefs later # prefs in this manager are shared self._settings_manager = settings.UserSettings(self._app) # set previously stored value for "show latest" latest_pubs_only = self._settings_manager.retrieve( "latest_publishes_only", True) self.ui.latest_publishes_only.setChecked(latest_pubs_only) # set previously stored value for "show pending" pending_versions_only = self._settings_manager.retrieve( "pending_versions_only", False) self.ui.pending_versions_only.setChecked(pending_versions_only) # navigation self.ui.navigation_home.clicked.connect(self._on_home_clicked) self.ui.navigation_next.clicked.connect(self._on_next_clicked) self.ui.navigation_prev.clicked.connect(self._on_prev_clicked) # search self.ui.search.clicked.connect(self._on_search_clicked) self.ui.cancel_search.clicked.connect(self._cancel_search) self.ui.search_input.entity_selected.connect( self._on_search_item_selected) # latest publishes only self.ui.latest_publishes_only.toggled.connect( self._on_latest_publishes_toggled) self.ui.pending_versions_only.toggled.connect( self._on_pending_versions_toggled) # tabs self.ui.entity_tab_widget.currentChanged.connect( self._load_entity_tab_data) self.ui.version_tab_widget.currentChanged.connect( self._load_version_tab_data) self.ui.publish_tab_widget.currentChanged.connect( self._load_publish_tab_data) # model to get the current user's details self._current_user_model = SgCurrentUserModel(self, self._task_manager) self._current_user_model.thumbnail_updated.connect( self._update_current_user) self._current_user_model.data_updated.connect( self._update_current_user) self._current_user_model.load() self.ui.current_user.clicked.connect(self._on_user_home_clicked) # top detail section self._details_model = SgEntityDetailsModel(self, self._task_manager) self._details_overlay = ShotgunModelOverlayWidget( self._details_model, self.ui.top_group) self._details_model.data_updated.connect(self._refresh_details) self._details_model.thumbnail_updated.connect( self._refresh_details_thumbnail) # hyperlink clicking self.ui.details_text_header.linkActivated.connect( self._on_link_clicked) self.ui.details_text_middle.linkActivated.connect( self._on_link_clicked) self.ui.details_thumb.playback_clicked.connect(self._playback_version) self.ui.note_reply_widget.entity_requested.connect( self.navigate_to_entity) self.ui.entity_activity_stream.entity_requested.connect( self.navigate_to_entity) self.ui.version_activity_stream.entity_requested.connect( self.navigate_to_entity) self.ui.entity_activity_stream.playback_requested.connect( self._playback_version) self.ui.version_activity_stream.playback_requested.connect( self._playback_version) # set up the UI tabs. Each tab has a model, a delegate, a view and # an associated enity type self._detail_tabs = {} # tabs on entity view idx = (self.ENTITY_PAGE_IDX, self.ENTITY_TAB_NOTES) self._detail_tabs[idx] = { "model_class": SgEntityListingModel, "delegate_class": ListItemDelegate, "view": self.ui.entity_note_view, "entity_type": "Note", } idx = (self.ENTITY_PAGE_IDX, self.ENTITY_TAB_VERSIONS) self._detail_tabs[idx] = { "model_class": SgVersionModel, "delegate_class": ListItemDelegate, "view": self.ui.entity_version_view, "entity_type": "Version", } idx = (self.ENTITY_PAGE_IDX, self.ENTITY_TAB_PUBLISHES) self._detail_tabs[idx] = { "model_class": SgLatestPublishListingModel, "delegate_class": ListItemDelegate, "view": self.ui.entity_publish_view, "entity_type": self._publish_entity_type, } idx = (self.ENTITY_PAGE_IDX, self.ENTITY_TAB_TASKS) self._detail_tabs[idx] = { "model_class": SgTaskListingModel, "delegate_class": ListItemDelegate, "view": self.ui.entity_task_view, "entity_type": "Task", } # tabs on publish view idx = (self.PUBLISH_PAGE_IDX, self.PUBLISH_TAB_HISTORY) self._detail_tabs[idx] = { "model_class": SgPublishHistoryListingModel, "delegate_class": ListItemDelegate, "view": self.ui.publish_history_view, "entity_type": self._publish_entity_type, } idx = (self.PUBLISH_PAGE_IDX, self.PUBLISH_TAB_CONTAINS) self._detail_tabs[idx] = { "model_class": SgPublishDependencyDownstreamListingModel, "delegate_class": ListItemDelegate, "view": self.ui.publish_upstream_view, "entity_type": self._publish_entity_type, } idx = (self.PUBLISH_PAGE_IDX, self.PUBLISH_TAB_USED_IN) self._detail_tabs[idx] = { "model_class": SgPublishDependencyUpstreamListingModel, "delegate_class": ListItemDelegate, "view": self.ui.publish_downstream_view, "entity_type": self._publish_entity_type, } # tabs on version view idx = (self.VERSION_PAGE_IDX, self.VERSION_TAB_NOTES) self._detail_tabs[idx] = { "model_class": SgEntityListingModel, "delegate_class": ListItemDelegate, "view": self.ui.version_note_view, "entity_type": "Note", } idx = (self.VERSION_PAGE_IDX, self.VERSION_TAB_PUBLISHES) self._detail_tabs[idx] = { "model_class": SgLatestPublishListingModel, "delegate_class": ListItemDelegate, "view": self.ui.version_publish_view, "entity_type": self._publish_entity_type, } # now initialize all tabs. This will add two model and delegate keys # to all the dicts for tab_dict in self._detail_tabs.values(): ModelClass = tab_dict["model_class"] DelegateClass = tab_dict["delegate_class"] self._app.log_debug("Creating %r..." % ModelClass) # create model tab_dict["model"] = ModelClass(tab_dict["entity_type"], tab_dict["view"], self._task_manager) # create proxy for sorting tab_dict["sort_proxy"] = QtGui.QSortFilterProxyModel(self) tab_dict["sort_proxy"].setSourceModel(tab_dict["model"]) # now use the proxy model to sort the data to ensure # higher version numbers appear earlier in the list # the history model is set up so that the default display # role contains the version number field in shotgun. # This field is what the proxy model sorts by default # We set the dynamic filter to true, meaning QT will keep # continously sorting. And then tell it to use column 0 # (we only have one column in our models) and descending order. tab_dict["sort_proxy"].setDynamicSortFilter(True) tab_dict["sort_proxy"].sort(0, QtCore.Qt.DescendingOrder) # set up model tab_dict["view"].setModel(tab_dict["sort_proxy"]) # set up a global on-click handler for tab_dict["view"].doubleClicked.connect( self._on_entity_doubleclicked) # create delegate tab_dict["delegate"] = DelegateClass(tab_dict["view"], self._action_manager) tab_dict["delegate"].change_work_area.connect( self._change_work_area) # hook up delegate renderer with view tab_dict["view"].setItemDelegate(tab_dict["delegate"]) # and set up a spinner overlay tab_dict["overlay"] = NotFoundModelOverlay(tab_dict["model"], tab_dict["view"]) if ModelClass == SgPublishHistoryListingModel: # this class needs special access to the overlay tab_dict["model"].set_overlay(tab_dict["overlay"]) # set up the all fields tabs self._entity_details_model = SgAllFieldsModel(self, self._task_manager) self._entity_details_overlay = ShotgunModelOverlayWidget( self._entity_details_model, self.ui.entity_info_widget) self._entity_details_model.data_updated.connect( self.ui.entity_info_widget.set_data) self.ui.entity_info_widget.link_activated.connect( self._on_link_clicked) self._version_details_model = SgAllFieldsModel( self.ui.version_info_widget, self._task_manager) self._version_details_model.data_updated.connect( self.ui.version_info_widget.set_data) self.ui.version_info_widget.link_activated.connect( self._on_link_clicked) self._publish_details_model = SgAllFieldsModel( self.ui.publish_info_widget, self._task_manager) self._publish_details_model.data_updated.connect( self.ui.publish_info_widget.set_data) self.ui.publish_info_widget.link_activated.connect( self._on_link_clicked) # the set work area overlay self.ui.set_context.change_work_area.connect(self._change_work_area) # kick off self._on_home_clicked() # register a startup splash screen splash_pix = QtGui.QPixmap(":/tk_multi_infopanel/splash.png") self._overlay.show_message_pixmap(splash_pix) QtCore.QCoreApplication.processEvents() QtCore.QTimer.singleShot(SPLASH_UI_TIME_MILLISECONDS, self._overlay.hide)
def setup_entity_model_view(self, entity_data): """ Given the entiy tab data, set up a model and view for the tab. This method will modify the `entity_data` dict passed in with the created model and view. :param entity_data: :type entity_data: dict :return: None """ # Check for the required entity data to set up the model and view. if not (entity_data.get("model_class", None) and entity_data.get("delegate_class", None) and entity_data.get("entity_type", None) and entity_data.get("view", None)): return ModelClass = entity_data["model_class"] DelegateClass = entity_data["delegate_class"] self._app.log_debug("Creating %r..." % ModelClass) # create model entity_data["model"] = ModelClass(entity_data["entity_type"], entity_data["view"], self._task_manager) # create proxy for sorting entity_data["sort_proxy"] = QtGui.QSortFilterProxyModel(self) entity_data["sort_proxy"].setSourceModel(entity_data["model"]) # now use the proxy model to sort the data to ensure # higher version numbers appear earlier in the list # the history model is set up so that the default display # role contains the version number field in shotgun. # This field is what the proxy model sorts by default # We set the dynamic filter to true, meaning QT will keep # continously sorting. And then tell it to use column 0 # (we only have one column in our models) and descending order. entity_data["sort_proxy"].setDynamicSortFilter(True) entity_data["sort_proxy"].sort(0, QtCore.Qt.DescendingOrder) # set up model entity_data["view"].setModel(entity_data["sort_proxy"]) # set up a global on-click handler for entity_data["view"].doubleClicked.connect( self._on_entity_doubleclicked) # create delegate entity_data["delegate"] = DelegateClass(entity_data["view"], self._action_manager) entity_data["delegate"].change_work_area.connect( self._change_work_area) # hook up delegate renderer with view entity_data["view"].setItemDelegate(entity_data["delegate"]) # and set up a spinner overlay entity_data["overlay"] = NotFoundModelOverlay(entity_data["model"], entity_data["view"]) if ModelClass == SgPublishHistoryListingModel: # this class needs special access to the overlay entity_data["model"].set_overlay(entity_data["overlay"])
def __init__(self, parent=None): """ Constructor """ # first, call the base class and let it do its thing. QtGui.QWidget.__init__(self, parent) # most of the useful accessors are available through the Application class instance # it is often handy to keep a reference to this. You can get it via the following method: self._app = sgtk.platform.current_bundle() self._action_manager = ActionManager(self) # set up an asynchronous shotgun retriever to pull down data self._sg_data_retriever = shotgun_data.ShotgunDataRetriever(self) self._sg_data_retriever.start() # register the data fetcher with the global schema manager CachedShotgunSchema.register_data_retriever(self._sg_data_retriever) # now load in the UI that was created in the UI designer self.ui = Ui_Dialog() self.ui.setupUi(self) # create a note updater to run operations on notes in the db self._note_updater = NoteUpdater(self._sg_data_retriever, self) # hook up a data retriever with all objects needing to talk to sg self.ui.search_input.set_data_retriever(self._sg_data_retriever) self.ui.note_reply_widget.set_data_retriever(self._sg_data_retriever) self.ui.entity_activity_stream.set_data_retriever( self._sg_data_retriever) self.ui.version_activity_stream.set_data_retriever( self._sg_data_retriever) # set up action menu self._menu = QtGui.QMenu() self._actions = [] self.ui.action_button.setMenu(self._menu) # our current object we are currently displaying self._current_location = None # track the history self._history_items = [] self._history_index = 0 # overlay to show messages self._overlay = overlay_module.ShotgunOverlayWidget(self) # figure out which type of publish this toolkit project is using self._publish_entity_type = sgtk.util.get_published_file_entity_type( self._app.sgtk) # create a settings manager where we can pull and push prefs later # prefs in this manager are shared self._settings_manager = settings.UserSettings(self._app) # set previously stored value for "show latest" latest_pubs_only = self._settings_manager.retrieve( "latest_publishes_only", True) self.ui.latest_publishes_only.setChecked(latest_pubs_only) # set previously stored value for "show pending" pending_versions_only = self._settings_manager.retrieve( "pending_versions_only", False) self.ui.pending_versions_only.setChecked(pending_versions_only) # navigation self.ui.navigation_home.clicked.connect(self._on_home_clicked) self.ui.navigation_next.clicked.connect(self._on_next_clicked) self.ui.navigation_prev.clicked.connect(self._on_prev_clicked) # search self.ui.search.clicked.connect(self._on_search_clicked) self.ui.cancel_search.clicked.connect(self._cancel_search) self.ui.search_input.entity_selected.connect( self._on_search_item_selected) # latest publishes only self.ui.latest_publishes_only.toggled.connect( self._on_latest_publishes_toggled) self.ui.pending_versions_only.toggled.connect( self._on_pending_versions_toggled) # tabs self.ui.entity_tab_widget.currentChanged.connect( self._load_entity_tab_data) self.ui.version_tab_widget.currentChanged.connect( self._load_version_tab_data) self.ui.publish_tab_widget.currentChanged.connect( self._load_publish_tab_data) # model to get the current user's details self._current_user_model = SgCurrentUserModel(self) self._current_user_model.thumbnail_updated.connect( self._update_current_user) self._current_user_model.data_updated.connect( self._update_current_user) self._current_user_model.load() self.ui.current_user.clicked.connect(self._on_user_home_clicked) # top detail section self._details_model = SgEntityDetailsModel(self.ui.top_group) self._details_model.data_updated.connect(self._refresh_details) self._details_model.thumbnail_updated.connect( self._refresh_details_thumbnail) # hyperlink clicking self.ui.details_text_header.linkActivated.connect( self._on_link_clicked) self.ui.details_text_middle.linkActivated.connect( self._on_link_clicked) self.ui.details_thumb.playback_clicked.connect(self._playback_version) self.ui.note_reply_widget.entity_requested.connect( self._navigate_to_entity) self.ui.entity_activity_stream.entity_requested.connect( self._navigate_to_entity) self.ui.version_activity_stream.entity_requested.connect( self._navigate_to_entity) self.ui.entity_activity_stream.playback_requested.connect( self._playback_version) self.ui.version_activity_stream.playback_requested.connect( self._playback_version) # set up the UI tabs. Each tab has a model, a delegate, a view and # an associated enity type self._detail_tabs = {} # tabs on entity view idx = (self.ENTITY_PAGE_IDX, self.ENTITY_TAB_NOTES) self._detail_tabs[idx] = { "model_class": SgEntityListingModel, "delegate_class": ListItemDelegate, "view": self.ui.entity_note_view, "entity_type": "Note" } idx = (self.ENTITY_PAGE_IDX, self.ENTITY_TAB_VERSIONS) self._detail_tabs[idx] = { "model_class": SgVersionModel, "delegate_class": ListItemDelegate, "view": self.ui.entity_version_view, "entity_type": "Version" } idx = (self.ENTITY_PAGE_IDX, self.ENTITY_TAB_PUBLISHES) self._detail_tabs[idx] = { "model_class": SgLatestPublishListingModel, "delegate_class": ListItemDelegate, "view": self.ui.entity_publish_view, "entity_type": self._publish_entity_type } idx = (self.ENTITY_PAGE_IDX, self.ENTITY_TAB_TASKS) self._detail_tabs[idx] = { "model_class": SgTaskListingModel, "delegate_class": ListItemDelegate, "view": self.ui.entity_task_view, "entity_type": "Task" } # tabs on publish view idx = (self.PUBLISH_PAGE_IDX, self.PUBLISH_TAB_HISTORY) self._detail_tabs[idx] = { "model_class": SgPublishHistoryListingModel, "delegate_class": ListItemDelegate, "view": self.ui.publish_history_view, "entity_type": self._publish_entity_type } idx = (self.PUBLISH_PAGE_IDX, self.PUBLISH_TAB_CONTAINS) self._detail_tabs[idx] = { "model_class": SgPublishDependencyDownstreamListingModel, "delegate_class": ListItemDelegate, "view": self.ui.publish_upstream_view, "entity_type": self._publish_entity_type } idx = (self.PUBLISH_PAGE_IDX, self.PUBLISH_TAB_USED_IN) self._detail_tabs[idx] = { "model_class": SgPublishDependencyUpstreamListingModel, "delegate_class": ListItemDelegate, "view": self.ui.publish_downstream_view, "entity_type": self._publish_entity_type } # tabs on version view idx = (self.VERSION_PAGE_IDX, self.VERSION_TAB_NOTES) self._detail_tabs[idx] = { "model_class": SgEntityListingModel, "delegate_class": ListItemDelegate, "view": self.ui.version_note_view, "entity_type": "Note" } idx = (self.VERSION_PAGE_IDX, self.VERSION_TAB_PUBLISHES) self._detail_tabs[idx] = { "model_class": SgLatestPublishListingModel, "delegate_class": ListItemDelegate, "view": self.ui.version_publish_view, "entity_type": self._publish_entity_type } # now initialize all tabs. This will add two model and delegate keys # to all the dicts for (idx, tab_dict) in self._detail_tabs.iteritems(): ModelClass = tab_dict["model_class"] DelegateClass = tab_dict["delegate_class"] self._app.log_debug("Creating %r..." % ModelClass) # create model if idx == (self.PUBLISH_PAGE_IDX, self.PUBLISH_TAB_HISTORY): # special case for the version history model tab_dict["model"] = ModelClass(tab_dict["entity_type"], self._sg_data_retriever, tab_dict["view"]) else: tab_dict["model"] = ModelClass(tab_dict["entity_type"], tab_dict["view"]) # create proxy for sorting tab_dict["sort_proxy"] = QtGui.QSortFilterProxyModel(self) tab_dict["sort_proxy"].setSourceModel(tab_dict["model"]) # now use the proxy model to sort the data to ensure # higher version numbers appear earlier in the list # the history model is set up so that the default display # role contains the version number field in shotgun. # This field is what the proxy model sorts by default # We set the dynamic filter to true, meaning QT will keep # continously sorting. And then tell it to use column 0 # (we only have one column in our models) and descending order. tab_dict["sort_proxy"].setDynamicSortFilter(True) tab_dict["sort_proxy"].sort(0, QtCore.Qt.DescendingOrder) # set up model tab_dict["view"].setModel(tab_dict["sort_proxy"]) # set up a global on-click handler for tab_dict["view"].doubleClicked.connect(self._on_entity_clicked) # create delegate tab_dict["delegate"] = DelegateClass(tab_dict["view"], self._action_manager) # hook up delegate renderer with view tab_dict["view"].setItemDelegate(tab_dict["delegate"]) # set up the all fields tabs self._entity_details_model = SgAllFieldsModel( self.ui.entity_info_widget) self._entity_details_model.data_updated.connect( self.ui.entity_info_widget.set_data) self.ui.entity_info_widget.link_activated.connect( self._on_link_clicked) self._version_details_model = SgAllFieldsModel( self.ui.version_info_widget) self._version_details_model.data_updated.connect( self.ui.version_info_widget.set_data) self.ui.version_info_widget.link_activated.connect( self._on_link_clicked) self._publish_details_model = SgAllFieldsModel( self.ui.publish_info_widget) self._publish_details_model.data_updated.connect( self.ui.publish_info_widget.set_data) self.ui.publish_info_widget.link_activated.connect( self._on_link_clicked) # kick off self._on_home_clicked()