fereria
1/21/2020 - 1:43 PM

UI_test

# -*- coding: utf-8 -*-

import sys
import os.path
from PySide2.QtWidgets import (QApplication, QMainWindow, QTreeView, QAbstractItemView, QVBoxLayout, QItemDelegate, QStyle)
from PySide2.QtCore import (QModelIndex, Qt, QAbstractItemModel, QObject)
from PySide2.QtUiTools import QUiLoader
from PySide2.QtGui import QBrush, QColor

from pxr import Usd, Sdf

sample_usd = "D:/work/usd_py36/usd/tree_view_sample.usda"


class TestView(QTreeView):

    def __init__(self, parent=None):
        super().__init__(parent)

        self.setDragEnabled(False)
        self.setAcceptDrops(True)
        self.setDropIndicatorShown(True)
        self.setDragDropOverwriteMode(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
            QApplication.setActiveWindow(self)  # Windowむりやりアクティブ
        else:
            super().dragEnterEvent(event)

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
            self.update()
        else:
            super().dragMoveEvent(event)

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            urls = event.mimeData().urls()
            for url in urls:
                print(self.model)
            event.accept()
        else:
            super().dropEvent(event)


class UISample(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.resize(600, 400)

        self.view = TestView()

        self.setCentralWidget(self.view)

        self.model = UsdStageModel(sample_usd)
        self.view.setModel(self.model)

        # self.delegate = TableDelegate()
        # self.view.setItemDelegate(self.delegate)


class PrimItem(object):

    def __init__(self, prim=None, parentItem=None):
        self._prim = prim
        self._parentItem = parentItem
        self._childItems = []

    def addChild(self, item):
        self._childItems.append(item)

    def getChild(self, row):
        if row <= len(self._childItems):
            return self._childItems[row]
        return None

    def getChildren(self):

        return self._childItems

    def getParentItem(self):
        return self._parentItem

    def getPrim(self):
        return self._prim

    def row(self):
        return self._parentItem.getChildren().index(self)

    def data(self, column):

        if column == 0:
            return self._prim.GetName()
        if column == 1:
            return self._prim.GetTypeName()
        if column == 2:
            return str(self._prim.GetPath())


BACKGROUND_BASE_COLOR_A = QColor(255, 255, 255)
BACKGROUND_BASE_COLOR_B = QColor(240, 240, 240)


class TableDelegate(QItemDelegate):

    def __init__(self, parent=None):
        super().__init__(parent)

    def paint(self, painter, option, index):

        bgColor = BACKGROUND_BASE_COLOR_A

        if option.state & QStyle.State_MouseOver:
            bgColor = BACKGROUND_BASE_COLOR_B

        brush = QBrush(bgColor)
        painter.fillRect(option.rect, brush)


class UsdStageModel(QAbstractItemModel):
    header = ["PrimName", "Type", "SdfPath"]

    def __init__(self, usdPath: str, parent=None):
        super().__init__(parent)

        # self.setupModelData(data.split('\n'), self.rootItem)
        self.stage = Usd.Stage.Open(usdPath)

        self.createModelTree()

    def createModelTree(self):

        # {SdfPath:Item}
        self.rootItem = PrimItem(self.stage.GetPrimAtPath("/"), None)
        self.prims = {Sdf.Path("/"): self.rootItem}
        for prim in self.stage.Traverse():
            parentPath = prim.GetParent().GetPath()
            item = PrimItem(prim, self.prims[parentPath])
            self.prims[parentPath].addChild(item)
            self.prims[prim.GetPath()] = item

    def columnCount(self, parent):
        return 3

    def data(self, index, role):

        if not index.isValid():
            return None

        if role != Qt.DisplayRole:
            return None

        item = index.internalPointer()
        return item.data(index.column())

    def flags(self, index):

        if not index.isValid():
            return Qt.NoItemFlags
        return Qt.ItemIsEnabled | Qt.ItemIsDropEnabled

    def index(self, row, column, parent):

        if not self.hasIndex(row, column, parent):
            return QModelIndex()

        if not parent.isValid():
            parentItem = self.rootItem
        else:
            parentItem = parent.internalPointer()

        childItem = parentItem.getChild(row)

        if childItem:
            index = self.createIndex(row, column, childItem)
            return index
        else:
            return QModelIndex()

    def parent(self, index):

        if not index.isValid():
            return QModelIndex()

        childItem = index.internalPointer()
        parentItem = childItem.getParentItem()

        if parentItem == self.rootItem:
            return QModelIndex()

        return self.createIndex(parentItem.row(), 0, parentItem)

    def rowCount(self, parent):

        if parent.column() > 0:
            return 0

        if not parent.isValid():
            parentItem = self.rootItem
        else:
            parentItem = parent.internalPointer()
        return len(parentItem.getChildren())

    def headerData(self, section, orientation, role):

        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.header[section]

    def supportedDropActions(self):
        return Qt.MoveAction | Qt.CopyAction


if __name__ == '__main__':
    app = QApplication(sys.argv)
    a = UISample()
    a.show()
    sys.exit(app.exec_())