217 lines
6.8 KiB
Python
217 lines
6.8 KiB
Python
from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex
|
|
import math
|
|
|
|
__all__ = ['TableModel', 'TableEdit']
|
|
|
|
|
|
class TableEdit(QAbstractTableModel):
|
|
def __init__(self, parent, data, fields):
|
|
super(TableEdit, self).__init__()
|
|
self._data = data
|
|
self._parent = parent
|
|
self._fields = fields
|
|
|
|
def data(self, index, role):
|
|
if role == Qt.DisplayRole:
|
|
row = index.row()
|
|
col = index.column()
|
|
val = self._data[row][col]
|
|
if self._fields[col]['type'] == 'integer':
|
|
return int(val)
|
|
return val
|
|
|
|
def rowCount(self, index):
|
|
return len(self._data)
|
|
|
|
def columnCount(self, index):
|
|
return len(self._fields) if self._fields else 0
|
|
|
|
def clearData(self):
|
|
self.beginRemoveRows(QModelIndex(), 0, len(self._data))
|
|
self._data = []
|
|
self.endRemoveRows()
|
|
self.layoutChanged.emit()
|
|
|
|
def get_data(self, index):
|
|
raw_value = self._data[index.row()]
|
|
return raw_value
|
|
|
|
def setData(self, index, value, role):
|
|
if role == Qt.EditRole:
|
|
if not value:
|
|
return False
|
|
row = index.row()
|
|
col = index.column()
|
|
if self._fields[col]['type'] == 'integer':
|
|
value = int(value)
|
|
self._data[row][col] = value
|
|
on_change = self._fields[col].get('change')
|
|
if on_change:
|
|
method = getattr(self._parent, on_change)
|
|
method(row)
|
|
return True
|
|
|
|
def flags(self, index):
|
|
col = index.column()
|
|
if self._fields[col].get('readonly'):
|
|
return Qt.ItemIsEnabled
|
|
else:
|
|
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
|
|
|
|
def headerData(self, section, orientation, role):
|
|
""" Set the headers to be displayed. """
|
|
if role != Qt.DisplayRole:
|
|
return None
|
|
if orientation == Qt.Horizontal:
|
|
for i in range(len(self._fields)):
|
|
if section == i:
|
|
return self._fields[i]['label']
|
|
return None
|
|
|
|
def add_record(self, rec):
|
|
length = len(self._data)
|
|
self.beginInsertRows(QModelIndex(), length, length)
|
|
self._data.append(rec)
|
|
self.endInsertRows()
|
|
return rec
|
|
|
|
def get_sum(self, col):
|
|
return sum([int(d[col]) for d in self._data])
|
|
|
|
|
|
class TableModel(QAbstractTableModel):
|
|
|
|
def __init__(self, model, fields):
|
|
super(TableModel, self).__init__()
|
|
self._fields = fields
|
|
self.model = model
|
|
self._data = []
|
|
|
|
def reset(self):
|
|
self.beginResetModel()
|
|
self._data = []
|
|
self.endResetModel()
|
|
|
|
def add_record(self, rec):
|
|
length = len(self._data)
|
|
self.beginInsertRows(QModelIndex(), length, length)
|
|
self._data.append(rec)
|
|
self.endInsertRows()
|
|
return rec
|
|
|
|
def get_id(self):
|
|
pass
|
|
|
|
def removeId(self, row, mdl_idx):
|
|
self.beginRemoveRows(mdl_idx, row, row)
|
|
id_ = self._data[row].get('id')
|
|
self._data.pop(row)
|
|
self.endRemoveRows()
|
|
return id_
|
|
|
|
def deleteRecords(self, ids):
|
|
pass
|
|
|
|
def rowCount(self, parent=None):
|
|
return len(self._data)
|
|
|
|
def columnCount(self, parent=None):
|
|
return len(self._fields) if self._fields else 0
|
|
|
|
def get_data(self, index):
|
|
raw_value = self._data[index.row()]
|
|
return raw_value
|
|
|
|
def get_value(self, data, field):
|
|
value = ''
|
|
list_ = field.split('.')
|
|
for l in list_:
|
|
if not data.get(l):
|
|
return None
|
|
value = data[l]
|
|
data = data[l]
|
|
return value
|
|
|
|
def data(self, index, role, field_name='name'):
|
|
field = self._fields[index.column()]
|
|
if role == Qt.DisplayRole:
|
|
index_row = self._data[index.row()]
|
|
raw_value = ''
|
|
if not index_row.get(field.get(field_name)):
|
|
if '.' in field.get(field_name):
|
|
raw_value = self.get_value(index_row, field[field_name])
|
|
else:
|
|
raw_value = index_row[field[field_name]]
|
|
|
|
digits = None
|
|
if field.get('digits'):
|
|
digits = 0
|
|
target_field = field.get('digits')[0]
|
|
target = None
|
|
try:
|
|
if index_row.get(target_field):
|
|
target = index_row[target_field]
|
|
elif '.' in target_field:
|
|
split_ = target_field.split('.')
|
|
target = index_row[split_[0]][split_[1]]
|
|
except:
|
|
pass
|
|
# if index_row.get(target_field):
|
|
# target = index_row[target_field]
|
|
if target:
|
|
group_digits = field.get('digits')[1]
|
|
if group_digits.get(target):
|
|
digits = group_digits.get(target)
|
|
eval_value = math.floor(float(raw_value)) - float(raw_value)
|
|
if target == 'u' and (eval_value > 0 or eval_value < 0):
|
|
digits = 2
|
|
if raw_value is None:
|
|
raw_value = ''
|
|
fmt_value = raw_value
|
|
if raw_value and field.get('format'):
|
|
field_format = field['format']
|
|
if digits or digits == 0:
|
|
field_format = field['format'] % str(digits)
|
|
if isinstance(raw_value, str) and raw_value != '':
|
|
raw_value = float(raw_value)
|
|
if field_format == '{:,d}':
|
|
raw_value = int(raw_value)
|
|
if raw_value:
|
|
fmt_value = field_format.format(raw_value)
|
|
return fmt_value
|
|
|
|
elif role == Qt.TextAlignmentRole:
|
|
align = Qt.AlignmentFlag(Qt.AlignVCenter | field['align'])
|
|
return align
|
|
else:
|
|
return None
|
|
|
|
def get_sum(self, field_target):
|
|
res = sum([d[field_target] for d in self._data])
|
|
return res
|
|
|
|
def update_record(self, rec, pos=None):
|
|
if pos is None:
|
|
pos = 0
|
|
for d in self._data:
|
|
if d['id'] == rec['id']:
|
|
break
|
|
pos += 1
|
|
self._data.pop(pos)
|
|
self._data.insert(pos, rec)
|
|
start_pos = self.index(pos, 0)
|
|
end_pos = self.index(pos, len(self._fields) - 1)
|
|
self.dataChanged.emit(start_pos, end_pos)
|
|
return rec
|
|
|
|
def headerData(self, section, orientation, role):
|
|
""" Set the headers to be displayed. """
|
|
if role != Qt.DisplayRole:
|
|
return None
|
|
elements = [f['description'] for f in self._fields]
|
|
if orientation == Qt.Horizontal:
|
|
for i in range(len(elements)):
|
|
if section == i:
|
|
return elements[i]
|
|
return None
|