mirror of
https://github.com/CopterExpress/clever-show.git
synced 2026-05-30 00:39:32 +00:00
Added ability to save and load widths of columns to config
This commit is contained in:
@@ -12,21 +12,21 @@ config_version = float(default='0.0')
|
||||
[[PRESETS]]
|
||||
current = string(default="DEFAULT")
|
||||
[[[DEFAULT]]]
|
||||
copter_id = boolean(default=True)
|
||||
git_version = boolean(default=True)
|
||||
animation_id = boolean(default=True)
|
||||
battery = boolean(default=True)
|
||||
fcu_status = boolean(default=True)
|
||||
calibration_status = boolean(default=True)
|
||||
mode = boolean(default=True)
|
||||
selfcheck = boolean(default=True)
|
||||
current_position = boolean(default=True)
|
||||
start_position = boolean(default=True)
|
||||
last_task = boolean(default=True)
|
||||
time_delta = boolean(default=True)
|
||||
config_version = boolean(default=True)
|
||||
copter_id = preset_param(default=list(True, 150))
|
||||
git_version = preset_param(default=list(True, 100))
|
||||
config_version = preset_param(default=list(True, 100))
|
||||
animation_id = preset_param(default=list(True, 100))
|
||||
battery = preset_param(default=list(True, 100))
|
||||
fcu_status = preset_param(default=list(True, 100))
|
||||
calibration_status = preset_param(default=list(True, 100))
|
||||
mode = preset_param(default=list(True, 100))
|
||||
selfcheck = preset_param(default=list(True, 100))
|
||||
current_position = preset_param(default=list(True, 100))
|
||||
start_position = preset_param(default=list(True, 100))
|
||||
last_task = preset_param(default=list(True, 100))
|
||||
time_delta = preset_param(default=list(True, 100))
|
||||
[[[__many__]]]
|
||||
__many__ = boolean
|
||||
__many__ = preset_param
|
||||
|
||||
[CHECKS]
|
||||
battery_min = float(default=50.0, min=0, max=100)
|
||||
|
||||
@@ -16,7 +16,7 @@ def save_preset(config, current, header_dict):
|
||||
presets = config.table_presets
|
||||
|
||||
for key in presets[HeaderEditWidget.default]:
|
||||
if key not in presets[current] and not header_dict[key]:
|
||||
if key not in presets[current] and not header_dict[key][0]:
|
||||
header_dict.pop(key)
|
||||
|
||||
presets[current] = header_dict
|
||||
@@ -33,7 +33,8 @@ class HeaderViewFilter(QObject):
|
||||
if event.type() == QEvent.Enter:
|
||||
# logicalIndex = self.header.logicalIndexAt(event.pos())
|
||||
self.parent().cellHover.emit(QModelIndex())
|
||||
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@@ -147,20 +148,36 @@ class CopterTableWidget(QTableView):
|
||||
if index_to != index_from:
|
||||
self.horizontalHeader().moveSection(index_from, index_to)
|
||||
|
||||
def load_columns(self, item_dict: dict=None):
|
||||
def load_columns(self, item_dict: dict = None):
|
||||
presets = self.config.table_presets
|
||||
if item_dict is None:
|
||||
item_dict = presets[self.config.table_presets_current]
|
||||
|
||||
item_dict.update({key: False for key in presets[HeaderEditWidget.default] if key not in item_dict})
|
||||
item_dict.update({key: (False, presets[HeaderEditWidget.default][key][1])
|
||||
for key in presets[HeaderEditWidget.default] if key not in item_dict})
|
||||
|
||||
self.set_column_order(list(item_dict.keys()))
|
||||
for name, show in item_dict.items(): # for index, name in enumerate(self.columns):
|
||||
self.setColumnHidden(self.columns.index(name), not show) # self.setColumnHidden(index, not item_dict.get(name, False))
|
||||
self.set_column_order(item_dict.keys())
|
||||
# self.set_column_widths({key: val[1] for key, val in item_dict.items()})
|
||||
|
||||
for name, value in item_dict.items(): # for index, name in enumerate(self.columns):
|
||||
index = self.columns.index(name)
|
||||
show, width = value
|
||||
self.setColumnHidden(index, not show) # self.setColumnHidden(index, not item_dict.get(name, False))
|
||||
self.setColumnWidth(index, width)
|
||||
|
||||
def _get_column_item(self, column):
|
||||
index = self.columns.index(column)
|
||||
presets = self.config.table_presets
|
||||
show = not self.isColumnHidden(index)
|
||||
# columnWidth is 0 when hidden, trying to get previous width from config or default
|
||||
width = self.columnWidth(index) or \
|
||||
presets[self.config.table_presets_current].get(column, 0)[1] or \
|
||||
presets[HeaderEditWidget.default][column][1]
|
||||
return show, width
|
||||
|
||||
@property
|
||||
def item_dict(self):
|
||||
return {column: not self.isColumnHidden(self.columns.index(column)) for column in self.current_columns}
|
||||
return {column: self._get_column_item(column) for column in self.current_columns}
|
||||
|
||||
def save_columns(self):
|
||||
current = self.config.table_presets_current
|
||||
@@ -180,8 +197,7 @@ class CopterTableWidget(QTableView):
|
||||
|
||||
@pyqtSlot(QtCore.QModelIndex)
|
||||
def on_double_click(self, index):
|
||||
col = index.column()
|
||||
if col == 7:
|
||||
if self.model.is_column(index, "selfcheck"):
|
||||
data = self.proxy_model.data(index, role=table.ModelDataRole)
|
||||
if data and data != "OK":
|
||||
self._show_info("Selfcheck info", data)
|
||||
@@ -254,7 +270,8 @@ class CopterTableWidget(QTableView):
|
||||
|
||||
|
||||
class HeaderListWidget(QListWidget):
|
||||
ColumnKeyRole = 998
|
||||
ColumnKeyRole = Qt.UserRole + 1000
|
||||
ColumnWidthRole = Qt.UserRole + 1001
|
||||
|
||||
dropped = QtCore.pyqtSignal(bool)
|
||||
|
||||
@@ -268,18 +285,21 @@ class HeaderListWidget(QListWidget):
|
||||
|
||||
def populate_items(self, item_dict: dict):
|
||||
self.clear()
|
||||
for name, visible in item_dict.items():
|
||||
for name, value in item_dict.items():
|
||||
visible, width = value
|
||||
flags = Qt.ItemIsUserCheckable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled
|
||||
state = Qt.Checked if visible else Qt.Unchecked
|
||||
|
||||
item = QListWidgetItem(table.CopterDataModel.columns_dict.get(name, "").strip() or name, self)
|
||||
item.setFlags(flags)
|
||||
item.setCheckState(state)
|
||||
item.setData(HeaderListWidget.ColumnKeyRole, name)
|
||||
item.setData(self.ColumnKeyRole, name)
|
||||
item.setData(self.ColumnWidthRole, width)
|
||||
|
||||
@property
|
||||
def item_dict(self):
|
||||
return {self.item(i).data(HeaderListWidget.ColumnKeyRole): bool(self.item(i).checkState())
|
||||
return {self.item(i).data(self.ColumnKeyRole):
|
||||
(bool(self.item(i).checkState()), self.item(i).data(self.ColumnWidthRole))
|
||||
for i in range(self.count())}
|
||||
|
||||
def dropEvent(self, event: QtGui.QDropEvent):
|
||||
@@ -307,8 +327,7 @@ class ActiveHeaderListWidget(HeaderListWidget):
|
||||
key = item.data(HeaderListWidget.ColumnKeyRole)
|
||||
if key is None:
|
||||
return
|
||||
self.source_widget.setColumnHidden(self.columns.index(key),
|
||||
not bool(item.checkState()))
|
||||
self.source_widget.setColumnHidden(self.columns.index(key), not bool(item.checkState()))
|
||||
|
||||
def dropEvent(self, event: QtGui.QDropEvent):
|
||||
super().dropEvent(event)
|
||||
@@ -332,7 +351,7 @@ class HeaderEditWidget(QtWidgets.QWidget):
|
||||
self.preset_widget = QtWidgets.QComboBox()
|
||||
self.header_widget = ActiveHeaderListWidget(self.source) \
|
||||
if self.menu_mode else HeaderListWidget()
|
||||
#self.header_widget.itemChanged.connect(partial(self.saved_signal.emit, False))
|
||||
# self.header_widget.itemChanged.connect(partial(self.saved_signal.emit, False))
|
||||
self.header_widget.model().dataChanged.connect(partial(self.saved_signal.emit, False))
|
||||
self.header_widget.dropped.connect(partial(self.saved_signal.emit, False))
|
||||
|
||||
@@ -404,13 +423,17 @@ class HeaderEditWidget(QtWidgets.QWidget):
|
||||
|
||||
self.previous = index
|
||||
presets = self.config.table_presets
|
||||
items = {key: value for key, value in presets[index].items()}
|
||||
items.update({key: False for key in presets[self.default] if key not in items})
|
||||
item_dict = {key: value for key, value in presets[index].items()}
|
||||
item_dict.update({key: (False, presets[self.default][key][1])
|
||||
for key in presets[self.default] if key not in item_dict})
|
||||
|
||||
if self.menu_mode:
|
||||
self.source.set_column_order(list(items.keys()))
|
||||
self.source.set_column_order(list(item_dict.keys())) # hidden\shown is hold by header widget's itemChanged
|
||||
for name, value in item_dict.items():
|
||||
self.source.setColumnWidth(self.source.columns.index(name), value[1])
|
||||
|
||||
self.config.table_presets_current = index
|
||||
self.header_widget.populate_items(items)
|
||||
self.header_widget.populate_items(item_dict)
|
||||
self.saved_signal.emit(True)
|
||||
|
||||
def add_preset(self):
|
||||
@@ -438,7 +461,7 @@ class HeaderEditWidget(QtWidgets.QWidget):
|
||||
return
|
||||
|
||||
reply = QMessageBox.question(None, "Action can't be undone", "Remove anyway?",
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
||||
|
||||
if reply != QMessageBox.Yes:
|
||||
return
|
||||
@@ -486,7 +509,7 @@ class HeaderEditDialog(QtWidgets.QDialog):
|
||||
unsaved = not saved
|
||||
self.unsaved = unsaved
|
||||
self.setWindowTitle(f"Column preset editor - {self.widget.preset_widget.currentText()}"
|
||||
+ "*"*unsaved)
|
||||
+ "*" * unsaved)
|
||||
|
||||
def closeEvent(self, event):
|
||||
if not self.unsaved:
|
||||
@@ -506,8 +529,11 @@ class HeaderEditDialog(QtWidgets.QDialog):
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
|
||||
|
||||
def except_hook(cls, exception, traceback):
|
||||
sys.__excepthook__(cls, exception, traceback)
|
||||
|
||||
|
||||
sys.excepthook = except_hook # for debugging (exceptions traceback)
|
||||
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
@@ -518,12 +544,14 @@ if __name__ == '__main__':
|
||||
# model.add_client(copter_table_models.StatedCopterData())
|
||||
|
||||
import config
|
||||
|
||||
c = config.ConfigManager()
|
||||
c.load_config_and_spec("config\server.ini")
|
||||
#print(c.config)
|
||||
#print(c._name_dict)
|
||||
# print(c.config)
|
||||
# print(c._name_dict)
|
||||
w1 = CopterTableWidget(model, c)
|
||||
w = HeaderEditWidget(w1, c)
|
||||
print(w1.item_dict)
|
||||
# print(*w1.current_columns, sep='\n')
|
||||
w.show()
|
||||
# w.show()
|
||||
app.exec()
|
||||
|
||||
@@ -354,8 +354,6 @@ class CopterDataModel(QtCore.QAbstractTableModel):
|
||||
|
||||
def __init__(self, checks=ModelChecks, formatter=ModelFormatter, data_model=StatedCopterData, parent=None):
|
||||
super(CopterDataModel, self).__init__(parent)
|
||||
# self.headers = (' copter ID ', ' version ', ' animation ID ', ' battery ', ' fcu_status ', ' sensors ',
|
||||
# ' mode ', ' checks ', ' current x y z yaw frame_id ', ' start x y z ', ' task ', 'dt')
|
||||
self.headers = list(self.columns_dict.values())
|
||||
self.data_contents = []
|
||||
|
||||
|
||||
15
config.py
15
config.py
@@ -3,7 +3,7 @@ import copy
|
||||
import collections
|
||||
|
||||
from configobj import ConfigObj, Section, flatten_errors
|
||||
from validate import Validator
|
||||
from validate import Validator, is_tuple, is_boolean, is_integer
|
||||
|
||||
|
||||
def modify_filename(path, pattern): # TODO move to core
|
||||
@@ -23,6 +23,11 @@ def parent_dir(path):
|
||||
return os.path.basename(os.path.normpath(path))
|
||||
|
||||
|
||||
def is_preset_param(value):
|
||||
parsed = is_tuple(value, min=2, max=2)
|
||||
return is_boolean(parsed[0]), is_integer(parsed[1], min=0)
|
||||
|
||||
|
||||
class ValidationError(ValueError):
|
||||
def __init__(self, message, config, errors):
|
||||
super(ValidationError, self).__init__(message)
|
||||
@@ -84,7 +89,7 @@ class ConfigManager:
|
||||
|
||||
def validate_config(self, config=None, copy_defaults=False):
|
||||
config = self.config if config is None else config
|
||||
vdt = Validator()
|
||||
vdt = Validator({"preset_param": is_preset_param})
|
||||
|
||||
test = config.validate(vdt, copy=copy_defaults, preserve_errors=True)
|
||||
if test != True: # Important syntax, do no change
|
||||
@@ -306,9 +311,13 @@ class ConfigManager:
|
||||
|
||||
if __name__ == '__main__':
|
||||
cfg = ConfigManager()
|
||||
cfg.load_from_file('Server/config/server.ini')
|
||||
cfg.load_from_file('Drone/config/client.ini')
|
||||
# cfg.load_from_file('Server/config/server.ini')
|
||||
#cfg.load_from_file('Drone/config/spec/configspec_client.ini')
|
||||
print(dict(cfg.full_dict(include_defaults=True)))
|
||||
cfg.config.pop("PRIVATE", None)
|
||||
print(cfg.config)
|
||||
|
||||
|
||||
# cfg.load_config_and_spec('Drone/config/client.ini')
|
||||
# #print(cfg.config.comments)
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import config
|
||||
from Server.copter_table_models import CopterDataModel
|
||||
|
||||
cfg_server = config.ConfigObj('SERVER/config/spec/configspec_server.ini')
|
||||
default = {key: 'boolean(default=True)' for key in CopterDataModel.columns}
|
||||
cfg_server = config.ConfigObj('SERVER/config/spec/configspec_server.ini', list_values=False)
|
||||
widths = {"copter_id": 150}
|
||||
default_width = 100
|
||||
|
||||
default = {key: f"preset_param(default=list(True, {widths.get(key, default_width)}))"
|
||||
for key in CopterDataModel.columns}
|
||||
|
||||
cfg_server['TABLE']['PRESETS']['DEFAULT'] = default
|
||||
|
||||
cfg_server.write()
|
||||
|
||||
Reference in New Issue
Block a user