def __init__(self, stage, role=None, parent=None): # type: (Usd.Stage, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> None """ Parameters ---------- stage : Usd.Stage role : Optional[Union[Type[OutlinerRole], OutlinerRole]] parent : Optional[QtGui.QWidget] """ assert isinstance(stage, Usd.Stage), 'A Stage instance is required' super(UsdOutliner, self).__init__(parent=parent) self._stage = stage self._dataModel = HierarchyBaseModel(stage=stage, parent=self) self._listener = Tf.Notice.Register(Usd.Notice.StageEditTargetChanged, self._OnEditTargetChanged, stage) self.setModal(False) self.UpdateTitle() if role is None: role = OutlinerRole self.role = role view = self._CreateView(stage, self.role) view.setColumnWidth(0, 360) view.setModel(self._dataModel) self.view = view delegate = OutlinerViewDelegate(stage, parent=view) view.setItemDelegate(delegate) self.menuBarBuilder = MenuBarBuilder( self, menuBuilders=role.GetMenuBarMenuBuilders(self), parent=self) layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(4, 4, 4, 4) layout.setSpacing(2) layout.addWidget(self.menuBarBuilder.menuBar) layout.addWidget(view) self.resize(900, 600) # Instances of child dialogs (for reference-counting purposes) self.editTargetDialog = None self.variantEditorDialog = None
def __init__(self, stage, role=None, parent=None): # type: (Usd.Stage, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> None """ Parameters ---------- stage : Usd.Stage role : Optional[Union[Type[OutlinerRole], OutlinerRole]] parent : Optional[QtGui.QWidget] """ super(UsdOutliner, self).__init__(parent=parent) self._stage = None self._listener = None self._dataModel = HierarchyBaseModel(stage=stage, parent=self) self.ResetStage(stage) if role is None: role = OutlinerRole self.role = role view = self._CreateView(stage, self.role) view.setColumnWidth(0, 360) view.setModel(self._dataModel) self.view = view delegate = OutlinerViewDelegate(stage, parent=view) view.setItemDelegate(delegate) self.stageChanged.connect(delegate.ResetStage) self.menuBarBuilder = MenuBarBuilder( self, menuBuilders=role.GetMenuBarMenuBuilders(self), parent=self) layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(4, 4, 4, 4) layout.setSpacing(2) layout.addWidget(self.menuBarBuilder.menuBar) layout.addWidget(view) # Instances of child dialogs (for reference-counting purposes) self._sharedLayerTextEditors = {} self.editTargetDialog = None self.variantEditorDialog = None
class UsdOutliner(QtWidgets.QWidget): """UsdStage editing application which displays the hierarchy of a stage.""" # Emitted when a new stage should be loaded into the outliners models stageChanged = QtCore.Signal(Usd.Stage) def __init__(self, stage, role=None, parent=None): # type: (Usd.Stage, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> None """ Parameters ---------- stage : Usd.Stage role : Optional[Union[Type[OutlinerRole], OutlinerRole]] parent : Optional[QtGui.QWidget] """ super(UsdOutliner, self).__init__(parent=parent) self._stage = None self._listener = None self._dataModel = HierarchyBaseModel(stage=stage, parent=self) self.ResetStage(stage) if role is None: role = OutlinerRole self.role = role view = self._CreateView(stage, self.role) view.setColumnWidth(0, 360) view.setModel(self._dataModel) self.view = view delegate = OutlinerViewDelegate(stage, parent=view) view.setItemDelegate(delegate) self.stageChanged.connect(delegate.ResetStage) self.menuBarBuilder = MenuBarBuilder( self, menuBuilders=role.GetMenuBarMenuBuilders(self), parent=self) layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(4, 4, 4, 4) layout.setSpacing(2) layout.addWidget(self.menuBarBuilder.menuBar) layout.addWidget(view) # Instances of child dialogs (for reference-counting purposes) self._sharedLayerTextEditors = {} self.editTargetDialog = None self.variantEditorDialog = None def _CreateView(self, stage, role): # type: (Usd.Stage, Union[Type[OutlinerRole], OutlinerRole]) -> QtWidgets.QAbstractItemView """Create the hierarchy view for the outliner. This is provided as a convenience for subclass implementations. Parameters ---------- stage : Usd.Stage role : Union[Type[OutlinerRole], OutlinerRole] Returns ------- QtWidgets.QAbstractItemView """ return OutlinerTreeView( contextMenuActions=role.GetContextMenuActions(self), contextProvider=self, parent=self) @property def stage(self): return self._stage def _LayerDialogEditTargetChangeCallback(self, newLayer): currentLayer = self.GetEditTargetLayer() if newLayer == currentLayer or not newLayer.permissionToEdit: return False if currentLayer.dirty: box = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Warning, 'Unsaved Layer Changes', 'The current edit target layer contains unsaved edits which ' 'will not be accessible after changing edit targets. Are you ' 'sure you want to switch?', buttons=QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes, parent=self) if box.exec_() != QtWidgets.QMessageBox.Yes: return False return True def GetMenuContext(self): # type: () -> OutlinerContext """ Returns ------- OutlinerContext """ selectedPrims = self.view.SelectedPrims() selectedPrim = selectedPrims[0] if selectedPrims else None return OutlinerContext(qtParent=self, outliner=self, stage=self._stage, editTargetLayer=self.GetEditTargetLayer(), selectedPrim=selectedPrim, selectedPrims=selectedPrims) def GetEditTargetLayer(self): # type: () -> Sdf.Layer """ Returns ------- Sdf.Layer """ if self._stage: return self._stage.GetEditTarget().GetLayer() def ResetStage(self, stage): """Reset the stage for this outliner and child dialogs. Parameters ---------- stage : Union[Usd.Stage, None] If None is given, this will clear the current stage """ self._stage = stage self._dataModel.ResetStage(stage) self.stageChanged.emit(stage) def _OnLayerTextEditorFinished(self, layer): dialog = self._sharedLayerTextEditors.pop(layer, None) if dialog: dialog.deleteLater() def GetSharedLayerTextEditorInstance(self, layer): # type: (Sdf.Layer, bool, Optional[QtWidgets.QWidget]) -> LayerTextEditorDialog """Convenience method to get or create a shared editor dialog instance. Parameters ---------- key : Any parent : Optional[QtWidgets.QWidget] Returns ------- LayerTextEditorDialog """ dialog = self._sharedLayerTextEditors.get(layer) if dialog is None: readOnly = not layer.permissionToEdit dialog = LayerTextEditorDialog(layer, readOnly=readOnly, parent=self) self._sharedLayerTextEditors[layer] = dialog dialog.finished.connect( lambda result: self._OnLayerTextEditorFinished(layer)) return dialog def ShowLayerTextDialog(self, layer=None): if layer is None: layer = self.GetEditTargetLayer() dialog = self.GetSharedLayerTextEditorInstance(layer) self.stageChanged.connect(dialog.close) dialog.show() dialog.raise_() dialog.activateWindow() def ShowEditTargetDialog(self): if not self.editTargetDialog: dialog = EditTargetDialog(self._stage, editTargetChangeCallback=self. _LayerDialogEditTargetChangeCallback, parent=self) self.stageChanged.connect(dialog.editor.ResetStage) self.editTargetDialog = dialog self.editTargetDialog.show() self.editTargetDialog.raise_() self.editTargetDialog.activateWindow()
class UsdOutliner(QtWidgets.QDialog): """UsdStage editing application which displays the hierarchy of a stage.""" def __init__(self, stage, role=None, parent=None): # type: (Usd.Stage, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> None """ Parameters ---------- stage : Usd.Stage role : Optional[Union[Type[OutlinerRole], OutlinerRole]] parent : Optional[QtGui.QWidget] """ assert isinstance(stage, Usd.Stage), 'A Stage instance is required' super(UsdOutliner, self).__init__(parent=parent) self._stage = stage self._dataModel = HierarchyBaseModel(stage=stage, parent=self) self._listener = Tf.Notice.Register(Usd.Notice.StageEditTargetChanged, self._OnEditTargetChanged, stage) self.setModal(False) self.UpdateTitle() if role is None: role = OutlinerRole self.role = role view = self._CreateView(stage, self.role) view.setColumnWidth(0, 360) view.setModel(self._dataModel) self.view = view delegate = OutlinerViewDelegate(stage, parent=view) view.setItemDelegate(delegate) self.menuBarBuilder = MenuBarBuilder( self, menuBuilders=role.GetMenuBarMenuBuilders(self), parent=self) layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(4, 4, 4, 4) layout.setSpacing(2) layout.addWidget(self.menuBarBuilder.menuBar) layout.addWidget(view) self.resize(900, 600) # Instances of child dialogs (for reference-counting purposes) self.editTargetDialog = None self.variantEditorDialog = None def _CreateView(self, stage, role): # type: (Usd.Stage, Union[Type[OutlinerRole], OutlinerRole]) -> QtWidgets.QAbstractItemView """Create the hierarchy view for the outliner. This is provided as a convenience for subclass implementations. Parameters ---------- stage : Usd.Stage role : Union[Type[OutlinerRole], OutlinerRole] Returns ------- QtWidgets.QAbstractItemView """ return OutlinerTreeView( self._dataModel, contextMenuActions=role.GetContextMenuActions(self), contextProvider=self, parent=self) @property def stage(self): return self._stage def _OnEditTargetChanged(self, notice, stage): self.UpdateTitle() def _LayerDialogEditTargetChangeCallback(self, newLayer): currentLayer = self.GetEditTargetLayer() if newLayer == currentLayer or not newLayer.permissionToEdit: return False if currentLayer.dirty: box = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Warning, 'Unsaved Layer Changes', 'The current edit target layer contains unsaved edits which ' 'will not be accessible after changing edit targets. Are you ' 'sure you want to switch?', buttons=QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes, parent=self) if box.exec_() != QtWidgets.QMessageBox.Yes: return False return True def GetMenuContext(self): # type: () -> OutlinerContext """ Returns ------- OutlinerContext """ selectedPrims = self.view.SelectedPrims() selectedPrim = selectedPrims[0] if selectedPrims else None return OutlinerContext(qtParent=self, outliner=self, stage=self._stage, editTargetLayer=self.GetEditTargetLayer(), selectedPrim=selectedPrim, selectedPrims=selectedPrims) def GetEditTargetLayer(self): # type: () -> Sdf.Layer """ Returns ------- Sdf.Layer """ return self._stage.GetEditTarget().GetLayer() def ResetStage(self): # TODO: Need to make sure this is still safe self._dataModel.ResetStage(self._stage) def UpdateTitle(self, identifier=None): # type: (Optional[str]) -> None """ Parameters ---------- identifier : Optional[str] If not provided, it is acquired from the curent edit target. """ if not identifier: identifier = self.GetEditTargetLayer().identifier self.setWindowTitle('Outliner - %s' % identifier) def ShowLayerTextDialog(self, layer=None): if layer is None: layer = self.GetEditTargetLayer() dialog = LayerTextEditorDialog.GetSharedInstance(layer, parent=self) dialog.show() dialog.raise_() dialog.activateWindow() def ShowEditTargetDialog(self): if not self.editTargetDialog: dialog = EditTargetDialog(self._stage, editTargetChangeCallback=self. _LayerDialogEditTargetChangeCallback, parent=self) self.editTargetDialog = dialog self.editTargetDialog.show() self.editTargetDialog.raise_() self.editTargetDialog.activateWindow() @classmethod def FromUsdFile(cls, usdFile, role=None, parent=None): # type: (str, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> UsdOutliner """ Parameters ---------- usdFile : str role : Optional[Union[Type[OutlinerRole], OutlinerRole]] parent : Optional[QtGui.QWidget] Returns ------- UsdOutliner """ with Usd.StageCacheContext(Usd.BlockStageCaches): stage = Usd.Stage.Open(usdFile, Usd.Stage.LoadNone) assert stage, 'Failed to open stage' stage.SetEditTarget(stage.GetSessionLayer()) return cls(stage, role=role, parent=parent)
model : HierarchyBaseModel """ self._filterModel.setSourceModel(model) if __name__ == "__main__": import sys from pxr.UsdQt.hierarchyModel import HierarchyBaseModel app = QtWidgets.QApplication(sys.argv) with Usd.StageCacheContext(UsdUtils.StageCache.Get()): stage = Usd.Stage.Open( '../usdQt/testenv/testUsdQtHierarchyModel/simpleHierarchy.usda') model = HierarchyBaseModel(stage) class Listener(QtCore.QObject): def __init__(self, parent=None): super(Listener, self).__init__(parent=parent) @QtCore.Slot() def OnPrimSelectionChanged(self, selected=None, deselected=None): for index in self.sender().selectedIndexes(): prim = index.data(role=roles.HierarchyPrimRole) # print(prim) editor = HierarchyEditor() editor.SetSourceModel(model) editor.show()