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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from __future__ import annotations
from PySide6.QtCore import QAbstractListModel, QByteArray, QModelIndex, Qt, Slot
from PySide6.QtGui import QColor
from PySide6.QtQml import QmlElement
# To be used on the @QmlElement decorator
# (QML_IMPORT_MINOR_VERSION is optional)
QML_IMPORT_NAME = "BaseModel"
QML_IMPORT_MAJOR_VERSION = 1
@QmlElement
class BaseModel(QAbstractListModel):
RatioRole = Qt.ItemDataRole.UserRole + 1
def __init__(self, parent=None):
super().__init__(parent=parent)
self.db = []
def rowCount(self, parent=QModelIndex()):
return len(self.db)
def roleNames(self):
default = super().roleNames()
default[self.RatioRole] = QByteArray(b"ratio")
default[Qt.ItemDataRole.BackgroundRole] = QByteArray(b"backgroundColor")
return default
def data(self, index, role: int):
if not self.db:
ret = None
elif not index.isValid():
ret = None
elif role == Qt.ItemDataRole.DisplayRole:
ret = self.db[index.row()]["text"]
elif role == Qt.ItemDataRole.BackgroundRole:
ret = self.db[index.row()]["bgColor"]
elif role == self.RatioRole:
ret = self.db[index.row()]["ratio"]
else:
ret = None
return ret
def setData(self, index, value, role):
if not index.isValid():
return False
if role == Qt.ItemDataRole.EditRole:
self.db[index.row()]["text"] = value
return True
@Slot(result=bool)
def append(self):
"""Slot to append a row at the end"""
return self.insertRow(self.rowCount())
def insertRow(self, row):
"""Insert a single row at row"""
return self.insertRows(row, 0)
def insertRows(self, row: int, count, index=QModelIndex()):
"""Insert n rows (n = 1 + count) at row"""
self.beginInsertRows(QModelIndex(), row, row + count)
# start database work
if len(self.db):
newid = max(x["id"] for x in self.db) + 1
else:
newid = 1
for i in range(count + 1): # at least one row
self.db.insert(
row, {"id": newid, "text": "new", "bgColor": QColor("purple"), "ratio": 0.2}
)
# end database work
self.endInsertRows()
return True
@Slot(int, int, result=bool)
def move(self, source: int, target: int):
"""Slot to move a single row from source to target"""
return self.moveRow(QModelIndex(), source, QModelIndex(), target)
def moveRow(self, sourceParent, sourceRow, dstParent, dstChild):
"""Move a single row"""
return self.moveRows(sourceParent, sourceRow, 0, dstParent, dstChild)
def moveRows(self, sourceParent, sourceRow, count, dstParent, dstChild):
"""Move n rows (n=1+ count) from sourceRow to dstChild"""
if sourceRow == dstChild:
return False
elif sourceRow > dstChild:
end = dstChild
else:
end = dstChild + 1
self.beginMoveRows(QModelIndex(), sourceRow, sourceRow + count, QModelIndex(), end)
# start database work
pops = self.db[sourceRow: sourceRow + count + 1]
if sourceRow > dstChild:
self.db = (
self.db[:dstChild]
+ pops
+ self.db[dstChild:sourceRow]
+ self.db[sourceRow + count + 1:]
)
else:
start = self.db[:sourceRow]
middle = self.db[dstChild: dstChild + 1]
endlist = self.db[dstChild + count + 1:]
self.db = start + middle + pops + endlist
# end database work
self.endMoveRows()
return True
@Slot(int, result=bool)
def remove(self, row: int):
"""Slot to remove one row"""
return self.removeRow(row)
def removeRow(self, row, parent=QModelIndex()):
"""Remove one row at index row"""
return self.removeRows(row, 0, parent)
def removeRows(self, row: int, count: int, parent=QModelIndex()):
"""Remove n rows (n=1+count) starting at row"""
self.beginRemoveRows(QModelIndex(), row, row + count)
# start database work
self.db = self.db[:row] + self.db[row + count + 1:]
# end database work
self.endRemoveRows()
return True
@Slot(result=bool)
def reset(self):
self.beginResetModel()
self.resetInternalData() # should work without calling it ?
self.endResetModel()
return True
def resetInternalData(self):
self.db = [
{"id": 3, "bgColor": QColor("red"), "ratio": 0.15, "text": "first"},
{"id": 1, "bgColor": QColor("blue"), "ratio": 0.1, "text": "second"},
{"id": 2, "bgColor": QColor("green"), "ratio": 0.2, "text": "third"},
]
|