-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcan_message_table.py
More file actions
168 lines (139 loc) · 5.28 KB
/
Copy pathcan_message_table.py
File metadata and controls
168 lines (139 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
from PySide6.QtCore import QAbstractTableModel, Qt, QModelIndex
from PySide6.QtWidgets import QTableView, QHeaderView
from can_enums import can_msg_table_header
class CANMessageTableModel(QAbstractTableModel):
def __init__(self, headers, parent=None):
"""
Initialize the CANMessageTableModel.
"""
super().__init__(parent)
self.headers = headers
self.data_rows = []
def rowCount(self, parent=QModelIndex()):
"""
Return the number of rows in the table.
"""
return len(self.data_rows)
def columnCount(self, parent=QModelIndex()):
"""
Return the number of columns in the table.
"""
return len(self.headers)
def data(self, index, role=Qt.DisplayRole):
"""
Return the data for a given cell.
"""
if not index.isValid():
return None
if role == Qt.DisplayRole:
if index.column() == 0:
return str(index.row() + 1)
return self.data_rows[index.row()][index.column() - 1]
return None
def headerData(self, section, orientation, role=Qt.DisplayRole):
"""
Return the header data for the table.
"""
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
return self.headers[section]
return None
def clear_table(self):
"""
Clear all rows in the table.
"""
self.beginResetModel()
self.data_rows = []
self.endResetModel()
def update_table(self, timestamp, can_id, extended, rtr, direction, dlc, data, overwrite=False, interpret=False):
"""
Update the table with a new CAN message.
- In overwrite or interpret mode, update the row with the same CAN ID or insert in ascending order.
- In normal mode, append the row sequentially.
"""
column_data = [
timestamp,
can_id,
extended,
rtr,
direction,
str(dlc),
data
]
if overwrite or interpret:
for row_index, row in enumerate(self.data_rows):
if row[1] == can_id:
self.data_rows[row_index] = column_data
self.dataChanged.emit(self.index(row_index, 0), self.index(row_index, len(column_data) - 1))
return row_index
insert_index = 0
for row_index, row in enumerate(self.data_rows):
if can_id < row[1]:
insert_index = row_index
break
else:
insert_index = len(self.data_rows)
self.beginInsertRows(QModelIndex(), insert_index, insert_index)
self.data_rows.insert(insert_index, column_data)
self.endInsertRows()
return insert_index
else:
self.beginInsertRows(QModelIndex(), len(self.data_rows), len(self.data_rows))
self.data_rows.append(column_data)
self.endInsertRows()
return len(self.data_rows) - 1
class CANMessageTable(QTableView):
def __init__(self, parent=None):
"""
Initialize the CANMessageTable as a QTableView with a custom model.
"""
super().__init__(parent)
self.headers = ["", "Timestamp", "ID", "Ext", "RTR", "Dir", "Len", "Data"]
self.timestamp_index = self.headers.index("Timestamp")
self.model = CANMessageTableModel(self.headers)
self.setModel(self.model)
self.setAlternatingRowColors(True)
self.setStyleSheet("""
QTableView {
background-color: #1F1F1F;
alternate-background-color: #2E2E2E;
gridline-color: #707070;
color: white;
border: 1px solid #4F4F4F;
}
""")
header = self.horizontalHeader()
header.setSectionResizeMode(QHeaderView.Interactive)
header.setSectionResizeMode(len(self.headers) - 1, QHeaderView.Stretch)
self.autoscroll_enabled = False
def clear_table(self):
"""
Clear all rows in the table.
"""
self.model.clear_table()
def update_table(self, timestamp, can_id, extended, rtr, direction, dlc, data, overwrite=False, interpret=False):
"""
Update the table with a new CAN message.
"""
row_index = self.model.update_table(timestamp, can_id, extended, rtr, direction, dlc, data, overwrite, interpret)
if overwrite:
self.resizeRowToContents(row_index)
if self.autoscroll_enabled:
self.scrollToBottom()
self.viewport().update()
def can_msg_table_set_header(self, header):
"""
Set the header for the CAN message table.
"""
if header == can_msg_table_header.TIME_STAMP_HEADER:
self.model.headers[self.timestamp_index] = "Timestamp"
print("[DEBUG] Timestamp set")
elif header == can_msg_table_header.TIME_DELTA_HEADER:
self.model.headers[self.timestamp_index] = "Time Delta"
print("[DEBUG] Time Delta header set")
else:
return False
def toggle_autoscroll(self, enabled):
"""
Enable or disable autoscrolling.
"""
self.autoscroll_enabled = enabled