diff options
Diffstat (limited to 'examples/serialbus/modbus/modbusclient/writeregistermodel.py')
-rw-r--r-- | examples/serialbus/modbus/modbusclient/writeregistermodel.py | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/examples/serialbus/modbus/modbusclient/writeregistermodel.py b/examples/serialbus/modbus/modbusclient/writeregistermodel.py new file mode 100644 index 000000000..07b1226de --- /dev/null +++ b/examples/serialbus/modbus/modbusclient/writeregistermodel.py @@ -0,0 +1,118 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +from enum import IntEnum + +from PySide6.QtCore import QAbstractTableModel, QBitArray, Qt, Signal, Slot + + +class Column(IntEnum): + NUM_COLUMN = 0 + COILS_COLUMN = 1 + HOLDING_COLUMN = 2 + COLUMN_COUNT = 3 + ROW_COUNT = 10 + + +class WriteRegisterModel(QAbstractTableModel): + + update_viewport = Signal() + + def __init__(self, parent=None): + super().__init__(parent) + self.m_coils = QBitArray(Column.ROW_COUNT, False) + self.m_number = 0 + self.m_address = 0 + self.m_holdingRegisters = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + + def rowCount(self, parent): + return Column.ROW_COUNT + + def columnCount(self, parent): + return Column.COLUMN_COUNT + + def data(self, index, role): + row = index.row() + column = index.column() + if not index.isValid() or row >= Column.ROW_COUNT or column >= Column.COLUMN_COUNT: + return None + + assert self.m_coils.size() == Column.ROW_COUNT + assert len(self.m_holdingRegisters) == Column.ROW_COUNT + + if column == Column.NUM_COLUMN and role == Qt.DisplayRole: + return f"{row}" + + if column == Column.COILS_COLUMN and role == Qt.CheckStateRole: # coils + return Qt.Checked if self.m_coils[row] else Qt.Unchecked + + # holding registers + if column == Column.HOLDING_COLUMN and role == Qt.DisplayRole: + reg = self.m_holdingRegisters[row] + return f"0x{reg:x}" + return None + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return None + + if orientation == Qt.Horizontal: + if section == Column.NUM_COLUMN: + return "#" + if section == Column.COILS_COLUMN: + return "Coils " + if section == Column.HOLDING_COLUMN: + return "Holding Registers" + return None + + def setData(self, index, value, role): + row = index.row() + column = index.column() + if not index.isValid() or row >= Column.ROW_COUNT or column >= Column.COLUMN_COUNT: + return False + + assert self.m_coils.size() == Column.ROW_COUNT + assert len(self.m_holdingRegisters) == Column.ROW_COUNT + + if column == Column.COILS_COLUMN and role == Qt.CheckStateRole: # coils + s = Qt.CheckState(int(value)) + if s == Qt.Checked: + self.m_coils.setBit(row) + else: + self.m_coils.clearBit(row) + self.dataChanged.emit(index, index) + return True + + if column == Column.HOLDING_COLUMN and role == Qt.EditRole: # holding registers + base = 16 if value.startswith("0x") else 10 + self.m_holdingRegisters[row] = int(value, base=base) + self.dataChanged.emit(index, index) + return True + + return False + + def flags(self, index): + row = index.row() + column = index.column() + flags = super().flags(index) + if not index.isValid() or row >= Column.ROW_COUNT or column >= Column.COLUMN_COUNT: + return flags + + if row < self.m_address or row >= (self.m_address + self.m_number): + flags &= ~Qt.ItemIsEnabled + + if column == Column.COILS_COLUMN: # coils + return flags | Qt.ItemIsUserCheckable + if column == Column.HOLDING_COLUMN: # holding registers + return flags | Qt.ItemIsEditable + return flags + + @Slot(int) + def set_start_address(self, address): + self.m_address = address + self.update_viewport.emit() + + @Slot(str) + def set_number_of_values(self, number): + self.m_number = int(number) + self.update_viewport.emit() |