You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
5.8 KiB
Python

from PyQt5.QtCore import Qt, QAbstractTableModel, QVariant, QTimer, QModelIndex, QEvent, QSize
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QMessageBox, QPushButton, QItemDelegate, QStyleOptionButton, QStyle, QWidget, QInputDialog, QHBoxLayout
from utils import Globals
import qtawesome
class RpcVarModel(QAbstractTableModel):
def __init__(self, header, parent=None):
# 新顺序:当前值、强制值、变量名、类型、下限、上限、客户端、强制按钮
self.header = ['当前值', '强制值', '变量名', '类型', '下限', '上限', '客户端', '操作']
super().__init__(parent)
self.datas = []
self.valueCache = {}
self.inputValues = {} # 行号->输入值
self.refreshTimer = QTimer()
self.refreshTimer.timeout.connect(self.refreshData)
self.refreshTimer.start(500) # 每秒刷新一次
self.table = parent
def refreshData(self):
"""刷新所有远程变量数据,并按类型排序"""
protocolManage = Globals.getValue('protocolManage')
if protocolManage and protocolManage.RpcServer:
allVars = protocolManage.RpcServer.broadcastRead()
temp = []
# print(allVars)
for client in allVars:
clientName = client.get('client', '')
variables = client.get('variables', {})
for varName, varInfo in variables.items():
row = [
varInfo.get('value', ''), # 当前值
self.inputValues.get(len(temp), ''),# 强制值(输入缓存)
varName, # 变量名
varInfo.get('type', ''), # 类型
varInfo.get('min', ''), # 下限
varInfo.get('max', ''), # 上限
clientName, # 客户端(倒数第二列)
'', # 强制按钮(最后一列)
]
temp.append(row)
# 按类型排序
temp.sort(key=lambda x: x[3])
self.datas = temp
self.table.proxy.invalidate()
def rowCount(self, parent=None):
return len(self.datas)
def columnCount(self, parent=None):
return len(self.header)
def data(self, index, role=Qt.DisplayRole):
if not index.isValid():
return QVariant()
row = index.row()
col = index.column()
if role == Qt.DisplayRole:
# 强制值输入列显示缓存值
if col == 1:
return self.inputValues.get(row, '')
return self.datas[row][col]
if role == Qt.TextAlignmentRole:
return Qt.AlignCenter
if role == Qt.BackgroundRole:
if row % 2 == 0:
return QColor('#EFEFEF')
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid() and index.column() == 1:
self.inputValues[index.row()] = value
self.dataChanged.emit(index, index)
return True
return False
def headerData(self, section, orientation, role=Qt.DisplayRole):
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
return self.header[section]
return QVariant()
def flags(self, index):
if not index.isValid():
return Qt.ItemIsEnabled
if index.column() == 1:
return Qt.ItemIsEnabled | Qt.ItemIsEditable
if index.column() == 7:
return Qt.ItemIsEnabled # 按钮列不可编辑
return Qt.ItemIsEnabled
from PyQt5.QtWidgets import QStyledItemDelegate, QPushButton, QStyleOptionButton, QStyle, QApplication
class RpcVarButtonDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
super(RpcVarButtonDelegate, self).__init__(parent)
def paint(self, painter, option, index):
if not self.parent().indexWidget(index) and index.column() == 7:
button = QPushButton(
qtawesome.icon('fa.play', color='#1fbb6f'),
'',
self.parent()
)
button.setIconSize(QSize(15, 15))
button.setStyleSheet('border:none;')
button.index = [index.row(), index.column()]
button.clicked.connect(lambda: self.force_action(button))
h_box_layout = QHBoxLayout()
h_box_layout.addWidget(button)
h_box_layout.setContentsMargins(2, 0, 0, 2)
h_box_layout.setAlignment(Qt.AlignCenter)
widget = QWidget()
widget.setLayout(h_box_layout)
self.parent().setIndexWidget(index, widget)
# 不再用QStyleOptionButton绘制
def force_action(self, sender):
model = self.parent().model
row = sender.index[0]
varName = model.datas[row][2]
minValue = model.datas[row][4]
maxValue = model.datas[row][5]
forceValue = model.inputValues.get(row, '')
if forceValue == '':
QMessageBox.warning(self.parent(), '提示', '请先输入强制值')
return
try:
protocolManage = Globals.getValue('protocolManage')
if protocolManage and protocolManage.RpcServer:
resp = protocolManage.RpcServer.writeVar(varName, float(forceValue))
if resp.get('result') == 'success':
QMessageBox.information(self.parent(), '提示', f'{varName} 强制成功!')
else:
reason = resp.get('reason', '')
QMessageBox.warning(self.parent(), '失败', f'{varName} 强制失败: {reason}')
except Exception as e:
QMessageBox.warning(self.parent(), '错误', f'强制失败: {e}')