コンテンツにスキップ

```python

!python3

-- coding: utf-8 --

import os.path
import sys

from PySide2.QtCore import QAbstractItemModel, QModelIndex, Qt
from PySide2.QtWidgets import QApplication, QDialog, QTreeView, QVBoxLayout, QMenu

class BaseItem(object):
def init(self, data=None, parent=None):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    self.parentItem = parent
    self.itemData = data
    self.childItems = []

def appendChild(self, item):

    self.childItems.append(item)

def removeChild(self, row):
    self.childItems.pop(row)

def child(self, row):
    if len(self.childItems) > row:
        return self.childItems[row]
    else:
        return None

def childCount(self):
    return len(self.childItems)

def columnCount(self):
    return 1

def data(self, column):
    if self.itemData is None:
        return ""
    return self.itemData['key']

def parent(self):
    return self.parentItem

def row(self):
    if self.parentItem:
        return self.parentItem.childItems.index(self)
    return 0

def clear(self):
    self.childItems = []

class TreeItem(BaseItem):

1
2
def __init__(self, data, parent=None):
    super(TreeItem, self).__init__(data=data, parent=parent)

class TreeModel(QAbstractItemModel):
def init(self, items=[], parent=None):
super(TreeModel, self).init(parent)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
    self.__items = items
    self.rootItem = BaseItem()
    # 現在のページ
    self.setItems(items)

def setItems(self, items):

    self.__items = items
    self.setupModelData()

def addItem(self, parent, text):

    item = parent.internalPointer()
    self.beginInsertRows(parent, item.childCount(), item.childCount())
    i = TreeItem(data={"key": text}, parent=item)
    item.appendChild(i)
    self.endInsertRows()

def removeItem(self, item):

    parent = self.parent(item)
    if parent.isValid():
        pItem = parent.internalPointer()
        self.beginRemoveRows(parent, item.row(), item.row())
        pItem.removeChild(item.row())
        self.endRemoveRows()

def columnCount(self, parent):

    if parent.isValid():
        return parent.internalPointer().columnCount()
    else:
        return self.rootItem.columnCount()

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.ItemIsSelectable

def headerData(self, section, orientation, role):
    if orientation == Qt.Horizontal and role == Qt.DisplayRole:
        return self.rootItem.data(section)
    return None

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

    if not parent.isValid():
        parentItem = self.rootItem
    else:
        parentItem = parent.internalPointer()
    childItem = parentItem.child(row)
    if childItem:
        return self.createIndex(row, column, childItem)
    else:
        return QModelIndex()

def parent(self, index):

    if not index.isValid():
        return QModelIndex()
    childItem = index.internalPointer()
    parentItem = childItem.parent()
    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 parentItem.childCount()

def setupModelData(self):
    """
    表示用のItemを再構築する
    """
    self.rootItem.clear()
    parents = {}
    self.beginResetModel()
    for item in self.__items:
        if item['parent'] in parents:
            p = parents[item['parent']]
        else:
            p = TreeItem(item, self.rootItem)
            self.rootItem.appendChild(p)
            parents[item['parent']] = p
        treeItem = TreeItem(item, p)
        p.appendChild(treeItem)
    self.endResetModel()

class UISample(QDialog):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def __init__(self, parent=None):
    super(UISample, self).__init__(parent)

    layout = QVBoxLayout()
    # カスタムUIを作成
    self.view = QTreeView()
    layout.addWidget(self.view)

    # てきとうにListに表示するItemの配列を作る
    data = []
    for i in range(5):
        data.append({'parent': 'hogehoge', 'key': 'homuhomu_' + str(i).zfill(3)})
    for i in range(5):
        data.append({'parent': 'fugafuga', 'key': 'homuhomu_' + str(i).zfill(3)})

    self.model = TreeModel(data)
    self.view.setModel(self.model)

    self.setLayout(layout)

    self.view.setContextMenuPolicy(Qt.CustomContextMenu)
    self.view.customContextMenuRequested.connect(self.listContext)

def listContext(self, pos):

    menu = QMenu(self.view)
    add = menu.addAction("Add")
    remove = menu.addAction("Remove")
    add.triggered.connect(self.addItem)
    remove.triggered.connect(self.removeItem)
    menu.exec_(self.view.mapToGlobal(pos))

def addItem(self):

    index = self.view.currentIndex()
    self.model.addItem(index, "HOGEHOGE")

def removeItem(self):

    index = self.view.currentIndex()
    self.model.removeItem(index)

if name == 'main':
app = QApplication(sys.argv)
a = UISample()
a.show()
sys.exit(app.exec_())```


最終更新日: 2022-06-15 15:27:00