mirror of
https://github.com/CopterExpress/clever-show.git
synced 2026-06-03 02:29:34 +00:00
Changed and optimized a lot checks behaviour
This commit is contained in:
@@ -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")
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user