0708更新
parent
3b075df941
commit
1eb5e3f2d3
@ -0,0 +1,135 @@
|
||||
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) # 每秒刷新一次
|
||||
|
||||
def refreshData(self):
|
||||
"""刷新所有远程变量数据,并按类型排序"""
|
||||
protocolManage = Globals.getValue('protocolManage')
|
||||
if protocolManage and protocolManage.RpcServer:
|
||||
allVars = protocolManage.RpcServer.broadcastRead()
|
||||
temp = []
|
||||
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.layoutChanged.emit()
|
||||
|
||||
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}')
|
Loading…
Reference in New Issue