Changed and optimized a lot checks behaviour

This commit is contained in:
Artem30801
2019-10-10 17:56:22 +03:00
parent d74377d31d
commit b26238461a
2 changed files with 100 additions and 48 deletions

View File

@@ -1,32 +1,67 @@
import sys
import re
import collections
import indexed
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt as Qt
class CopterData:
class_attrs = collections.OrderedDict([('copter_id', None), ('anim_id', None), ('batt_v', None), ('batt_p', None),
('sys_status', None), ('cal_status', None), ('selfcheck', None), ('position', None), ("time_delta", None),
("client", None), ("checked", 0)], )
class_basic_attrs = indexed.IndexedOrderedDict([('copter_id', None), ('anim_id', None),
('batt_v', None), ('batt_p', None),
('sys_status', None), ('cal_status', None), ('selfcheck', None),
('position', None), ("time_delta", None),
("client", None), ])
def __init__(self, **kwargs):
self.attrs = self.class_attrs.copy()
self.attrs.update(kwargs)
self.attrs_dict = self.class_basic_attrs.copy()
self.attrs_dict.update(kwargs)
for attr, value in self.attrs.items():
for attr, value in self.attrs_dict.items():
setattr(self, attr, value)
def __getitem__(self, key):
return getattr(self, list(self.attrs.keys())[key])
return getattr(self, self.attrs_dict.keys()[key])
def __setitem__(self, key, value):
setattr(self, list(self.attrs.keys())[key], value)
setattr(self, self.attrs_dict.keys()[key], value)
class StatedCopterData(CopterData):
class_basic_states = indexed.IndexedOrderedDict([("checked", 0), ("selfchecked", None), ("takeoff_ready", None),
("copter_id", True), ])
def __init__(self, **kwargs):
self.states = CopterData(**self.class_basic_states)
super(StatedCopterData, self).__init__(**kwargs)
def __setattr__(self, key, value):
self.__dict__[key] = value
if key in self.class_basic_attrs.keys():
try:
self.states.__dict__[key] = \
Checks.all_checks[self.attrs_dict.keys().index(key)](value)
except KeyError: # No check present for that col
pass
else: # update selfchecked and takeoff_ready
self.states.__dict__["selfchecked"] = all(
[self.states[i] for i in Checks.all_checks.keys()]
)
self.states.__dict__["takeoff_ready"] = all(
[self.states[i] for i in Checks.takeoff_checklist]
)
class Checks:
all_checks = {}
takeoff_checklist = (2, 3, 4, 5, 6)
class CopterDataModel(QtCore.QAbstractTableModel):
checks = {}
selected_ready_signal = QtCore.pyqtSignal(bool)
selected_takeoff_ready_signal = QtCore.pyqtSignal(bool)
selected_flip_ready_signal = QtCore.pyqtSignal(bool)
@@ -35,7 +70,8 @@ class CopterDataModel(QtCore.QAbstractTableModel):
def __init__(self, parent=None):
super(CopterDataModel, self).__init__(parent)
self.headers = ('copter ID', ' animation ID ', 'batt V', 'batt %', ' system ', 'calibration', 'selfcheck', 'current x y z yaw frame_id', 'time delta')
self.headers = ('copter ID', ' animation ID ', 'batt V', 'batt %', ' system ',
'calibration', 'selfcheck', 'current x y z yaw frame_id', 'time delta')
self.data_contents = []
self.first_col_is_checked = False
@@ -48,20 +84,21 @@ class CopterDataModel(QtCore.QAbstractTableModel):
self.endInsertRows()
def user_selected(self):
return filter(lambda x: x.checked == Qt.Checked, self.data_contents)
def user_selected(self, contents=()):
contents = contents or self.data_contents
return filter(lambda x: x.states.checked == Qt.Checked, contents)
def selfchecked_ready(self, contents=()):
contents = contents or self.data_contents
return filter(lambda x: all_checks(x), contents)
return filter(lambda x: x.states.selfchecked, contents)
def takeoff_ready(self, contents=()):
contents = contents or self.data_contents
return filter(lambda x: takeoff_checks(x), contents)
return filter(lambda x: x.states.takeoff_ready, contents)
def flip_ready(self, contents=()):
contents = contents or self.data_contents
return filter(lambda x: flip_checks(x), contents)
return filter(lambda x: flip_checks(x), contents) # possibly change as takeoff checks
def calibrating(self, contents=()):
contents = contents or self.data_contents
@@ -85,15 +122,16 @@ class CopterDataModel(QtCore.QAbstractTableModel):
def data(self, index, role=Qt.DisplayRole):
row = index.row()
col = index.column()
#print('row {}, col {}, role {}'.format(row, col, role))
if role == Qt.DisplayRole:
#print(self.data_contents[row][col])
return self.data_contents[row][col] or ""
elif role == Qt.BackgroundRole:
if col in self.checks.keys():
item = self.data_contents[row][col]
result = self.checks[col](item)
try:
item = self.data_contents[row]
result = item.states[col]
except KeyError:
return QtGui.QBrush(Qt.white)
else:
if result is None:
return QtGui.QBrush(Qt.yellow)
if result:
@@ -102,19 +140,22 @@ class CopterDataModel(QtCore.QAbstractTableModel):
return QtGui.QBrush(Qt.red)
elif role == Qt.CheckStateRole and col == 0:
return self.data_contents[row].checked
return self.data_contents[row].states.checked
if role == QtCore.Qt.TextAlignmentRole and col != 0:
return QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter
def update_model(self, index=QtCore.QModelIndex()):
#self.modelReset.emit()
self.selected_ready_signal.emit(set(self.user_selected()).issubset(self.selfchecked_ready()))
self.selected_takeoff_ready_signal.emit(set(self.user_selected()).issubset(self.takeoff_ready()))
self.selected_flip_ready_signal.emit(set(self.user_selected()).issubset(self.flip_ready()))
self.selected_calibrating_signal.emit(set(self.user_selected()).issubset(self.calibrating()))
self.selected_calibration_ready_signal.emit(set(self.user_selected()).issubset(self.calibration_ready()))
self.dataChanged.emit(index, index, (QtCore.Qt.EditRole,))
def update_model(self, index=QtCore.QModelIndex(), role=QtCore.Qt.EditRole):
selected = set(self.user_selected())
self.selected_ready_signal.emit(selected.issubset(self.selfchecked_ready()))
self.selected_takeoff_ready_signal.emit(selected.issubset(self.takeoff_ready()))
self.selected_flip_ready_signal.emit(selected.issubset(self.flip_ready()))
self.selected_calibrating_signal.emit(selected.issubset(self.calibrating()))
self.selected_calibration_ready_signal.emit(selected.issubset(self.calibration_ready()))
self.dataChanged.emit(index, index, (role,))
@QtCore.pyqtSlot()
def setData(self, index, value, role=Qt.EditRole):
@@ -122,27 +163,26 @@ class CopterDataModel(QtCore.QAbstractTableModel):
return False
if role == Qt.CheckStateRole:
self.data_contents[index.row()].checked = value
self.data_contents[index.row()].states.checked = value
elif role == Qt.EditRole:
self.data_contents[index.row()][index.column()] = value
self.update_model(index)
else:
return False
self.update_model(index, role)
return True
def select_all(self):
self.first_col_is_checked = not self.first_col_is_checked
for copter in self.data_contents:
copter.checked = int(self.first_col_is_checked)*2
for row in range(len(self.data_contents)):
self.update_model(self.index(row, 0))
for row_num, copter in enumerate(self.data_contents):
copter.states.checked = int(self.first_col_is_checked)*2
self.update_model(self.index(row_num, 0), Qt.CheckStateRole)
def flags(self, index):
roles = Qt.ItemIsSelectable | Qt.ItemIsEnabled
if index.column() == 0:
roles |= Qt.ItemIsUserCheckable
roles |= Qt.ItemIsUserCheckable #| Qt.ItemIsEditable
return roles
@QtCore.pyqtSlot(int, int, QtCore.QVariant)
@@ -156,7 +196,7 @@ class CopterDataModel(QtCore.QAbstractTableModel):
def col_check(col):
def inner(f):
CopterDataModel.checks[col] = f
Checks.all_checks[col] = f
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
@@ -172,42 +212,49 @@ def check_anim(item):
return None
return str(item) != 'No animation'
@col_check(2)
def check_bat_v(item):
if not item:
return None
return float(item) > 3.2
@col_check(3)
def check_bat_p(item):
if not item:
return None
return float(item) > 30
@col_check(4)
def check_sys_status(item):
if not item:
return None
return item == "STANDBY"
@col_check(5)
def check_cal_status(item):
if not item:
return None
return item == "OK"
@col_check(6)
def check_selfcheck(item):
if not item:
return None
return item == "OK"
@col_check(7)
def check_cal_status(item):
if not item:
return None
return True
@col_check(8)
def check_time_delta(item):
if not item:
@@ -216,35 +263,40 @@ def check_time_delta(item):
def all_checks(copter_item):
for col, check in CopterDataModel.checks.items():
for col, check in Checks.all_checks.items():
if not check(copter_item[col]):
return False
return True
def takeoff_checks(copter_item):
for i in range(5):
if not CopterDataModel.checks[2+i](copter_item[2+i]):
for col in Checks.takeoff_checklist:
if not Checks.all_checks[col](copter_item[col]):
return False
return True
def flip_checks(copter_item):
for i in range(5):
if 2+i != 4:
if not CopterDataModel.checks[2+i](copter_item[2+i]):
for col in Checks.takeoff_checklist:
if col != 4:
if not Checks.all_checks[col](copter_item[col]):
return False
else:
if copter_item[4] != "ACTIVE":
return False
return True
def calibrating_check(copter_item):
return copter_item[5] == "CALIBRATING"
def calibration_ready_check(copter_item):
if not CopterDataModel.checks[4](copter_item[4]):
if not Checks.all_checks[4](copter_item[4]):
return False
return not calibrating_check(copter_item)
class CopterProxyModel(QtCore.QSortFilterProxyModel):
def __init__(self, parent=None):
super(CopterProxyModel, self).__init__(parent)
@@ -296,9 +348,9 @@ if __name__ == '__main__':
tableView.setSortingEnabled(True)
tableView.show()
myModel.add_client(CopterData(copter_id=1000, checked=0, time_utc=1))
myModel.add_client(CopterData(checked=2, selfcheck="OK", time_utc=2))
myModel.add_client(CopterData(checked=2, selfcheck="not ok", time_utc="no"))
myModel.add_client(StatedCopterData(copter_id=1000, checked=0, time_utc=1))
myModel.add_client(StatedCopterData(checked=2, selfcheck="OK", time_utc=2))
myModel.add_client(StatedCopterData(checked=2, selfcheck="not ok", time_utc="no"))
myModel.setData(myModel.index(0, 1), "test")

View File

@@ -109,7 +109,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.ui.action_select_all_rows.triggered.connect(self.model.select_all)
def new_client_connected(self, client: Client):
self.signals.add_client_signal.emit(CopterData(copter_id=client.copter_id, client=client))
self.signals.add_client_signal.emit(StatedCopterData(copter_id=client.copter_id, client=client))
def init_ui(self):
# Connecting