from PyQt5 import QtCore from PyQt5.QtWidgets import QHeaderView, QStyle, QStyleOptionButton, QTableView, QAbstractItemView, QDesktopWidget from PyQt5.QtCore import (pyqtSignal, Qt, QRect) from PyQt5.QtWidgets import QTableView from .ModbusModel import * from .AnalogModel import * from .HartModel import * from .HartSimulateModel import * from .TCRTDModel import * from .RpcVarModel import RpcVarModel, RpcVarButtonDelegate from model.ProjectModel.VarManage import * from UI.VarManages.Thread import RTDTCThread, AnalogThread, HartSimulateThread # from UI.ProjectManages.ProjectModel import BackgroundDelegate from utils import Globals class BackgroundDelegate(QtWidgets.QStyledItemDelegate): def __init__(self, *args): super(BackgroundDelegate, self).__init__(*args) self.setObjectName('item') def sizeHint(self, option, index): """设置项目的尺寸提示,确保足够的高度""" size = super().sizeHint(option, index) size.setHeight(max(46, size.height())) # 最小高度60px return size def paint(self, painter, option, index): # 确保绘制区域有足够的高度 if index.data(QtCore.Qt.BackgroundRole): height = option.rect.height() top = option.rect.top() # 减少高度调整,保持更多的绘制区域 option.rect.setHeight(max(46, height - 4)) # 最小保持56px高度 option.rect.moveTop(top + 2) painter.fillRect(option.rect, index.data(QtCore.Qt.BackgroundRole)) super().paint(painter, option, index) class CheckBoxHeader(QHeaderView): checkClicked = pyqtSignal(bool) sectionClicked = pyqtSignal(int) _x_offset = 15 _y_offset = 15 _width = 25 _height = 25 def __init__(self, orientation=Qt.Horizontal, parent=None, changeY = None): self.isOn = False self.changeY = changeY super(CheckBoxHeader, self).__init__(orientation, parent) def paintSection(self, painter, rect, logicalIndex): painter.save() super(CheckBoxHeader, self).paintSection(painter, rect, logicalIndex) painter.restore() if self.changeY: self._y_offset = int((rect.height()-self._width)/2.) else: self._y_offset = int((rect.height()-self._width)/2.) if logicalIndex == 0: option = QStyleOptionButton() option.rect = QRect(rect.x() + self._x_offset, rect.y() + self._y_offset, self._width, self._height) option.state = QStyle.State_Enabled | QStyle.State_Active if self.isOn: option.state |= QStyle.State_On else: option.state |= QStyle.State_Off self.style().drawControl(QStyle.CE_CheckBox, option, painter) def mousePressEvent(self, event): index = self.logicalIndexAt(event.pos()) if 0 == index: x = self.sectionPosition(index) if x + self._x_offset < event.pos().x() < x + self._x_offset + self._width and self._y_offset < event.pos().y() < self._y_offset + self._height: if self.isOn: self.isOn = False else: self.isOn = True self.checkClicked.emit(self.isOn) self.update() else: self.sectionClicked.emit(index) super(CheckBoxHeader, self).mousePressEvent(event) class VarTableView(QTableView): def __init__(self, modbusType, parent=None): super(VarTableView, self).__init__(parent) self.parent = parent self.modbusType = modbusType self.setHeader() self.setupUi() def setHeader(self): self.delegate = BackgroundDelegate(self) self.setItemDelegate(self.delegate) self.setItemDelegateForColumn(11, ModbusButtonDelegate(self)) self.setItemDelegateForColumn(5, ModbusTypeBox(self)) self.setItemDelegateForColumn(10, ModbusVarModelBox(self)) self.model = VarTableModel([' ID', '强制值', '当前值', '变量名', '变量描述', '变量类型', '从站地址', '寄存器地址', '工程量下限', '工程量上限', '值类型', '操作'], [], modbusType = self.modbusType, table = self) def setupUi(self): self.setShowGrid(False) # self.setAlternatingRowColors(True) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setModel(self.model) self.header = CheckBoxHeader() self.header.setStretchLastSection(True) self.header.checkClicked.connect(self.model.headerClick) self.setHorizontalHeader(self.header) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setupColumnWidths() self.header.setObjectName('paramHeader') self.header.setSectionResizeMode(0, QHeaderView.Fixed) self.header.resizeSection(0, 70) # 设置行高 self.verticalHeader().setDefaultSectionSize(50) self.verticalHeader().setMinimumSectionSize(50) self.verticalHeader().hide() def setupColumnWidths(self): self.setCustomColumnWidths([0.9, 0.9, 0.9, 1, 1, 1.4, 1, 1, 1, 1, 0.9, 1.3]) def setCustomColumnWidths(self, ratios): # 计算总比例 totalRatio = sum(ratios) # 获取窗口宽度 screen = QDesktopWidget().screenGeometry() width = screen.width() - 300 # 根据比例设置每列的宽度 for i, ratio in enumerate(ratios): columnWidth = int(width * (ratio / totalRatio)) self.setColumnWidth(i, columnWidth) class HartTableView(VarTableView): def __init__(self, parent=None): super(HartTableView, self).__init__(parent) def setHeader(self): self.delegate = BackgroundDelegate(self) self.setItemDelegate(self.delegate) self.setItemDelegateForColumn(9, HartButtonDelegate(self)) self.setItemDelegateForColumn(8, HartVarModelBox(self)) self.model = HartModel([' ID', '仪器名', '描述', '电流值', '参数1', '参数2','参数3', '参数4', '值类型','操作'], [], table=self) def setupColumnWidths(self): self.header.setSectionResizeMode(QHeaderView.Stretch) class TcRtdTableView(VarTableView): def __init__(self, parent=None): super(TcRtdTableView, self).__init__(parent) self.delegate = BackgroundDelegate(self) self.setItemDelegate(self.delegate) self.setItemDelegateForColumn(6, TcRtdTypeDelegate(self)) self.valueList = [0] * 16 self.mvList = [0] * 16 self.setupColumnWidths() # self.workThread = RTDTCThread(self) # Globals.setValue('RTDTCThread', self.workThread) # self.workThread.getValueList.connect(self.getValueList) def setupColumnWidths(self): self.header.setSectionResizeMode(QHeaderView.Stretch) self.setCustomColumnWidths([1.2, 0.9, 0.9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) def setHeader(self): self.setItemDelegateForColumn(12, TcRtdButtonDelegate(self)) self.setItemDelegateForColumn(11, TcRtdVarModelBox(self)) self.model = TcRtdModel([' ID', '强制值', '当前值', '变量名', '通道序号', '变量描述', '变量类型', '工程量下限', '工程量上限', '单位', '补偿值', '值类型', '操作'], [], table=self) class AnalogTableView(VarTableView): def __init__(self, parent=None): super(AnalogTableView, self).__init__(parent) # self.valueList = [0] * 8 + [0] * 8 + [0] * 16 + [0] * 8 + [0] * 8 + [0] * 8 # self.realList = [0] * 8 + [0] * 8 + [0] * 16 + [0] * 8 + [0] * 8 + [0] * 8 # self.workThread = AnalogThread(self) # Globals.setValue('AnalogThread', self.workThread) self.delegate = BackgroundDelegate(self) self.setItemDelegate(self.delegate) self.setupColumnWidths() def setupColumnWidths(self): self.setCustomColumnWidths([0.8, 0.8, 0.8, 1.8, 1, 1.4, 0.8, 0.8, 1, 1, 1, 1]) def setHeader(self): self.setItemDelegateForColumn(11, AnalogButtonDelegate(self)) self.setItemDelegateForColumn(10, AnalogVarModelBox(self)) self.model = AnalogModel([' ID', '强制值', '当前值', '变量名', '通道序号', '变量描述', '变量类型', '工程量下限', '工程量上限', '单位', '值类型', '操作'], [], table=self) class HartSimulateTableView(VarTableView): def __init__(self, parent=None): super(HartSimulateTableView, self).__init__(parent) self.delegate = BackgroundDelegate(self) self.setItemDelegate(self.delegate) self.valueList = [] # self.realList = [0] * 8 + [0] * 8 + [0] * 8 self.workThread = HartSimulateThread(self) Globals.setValue('HartSimulateThread', self.workThread) def setupColumnWidths(self): self.header.setSectionResizeMode(QHeaderView.Stretch) def setHeader(self): self.setItemDelegateForColumn(10, HartSimulateButtonDelegate(self)) self.setItemDelegateForColumn(9, HartSimulateVarModelBox(self)) self.model = HartSimulateModel([' ID', '仪器名', '描述', '主变量', '过程变量1', '过程变量2', '过程变量3', '工程量下限', '工程量上限', '值类型','操作'], [], table=self) class RpcVarTableView(QTableView): def __init__(self, parent=None): super(RpcVarTableView, self).__init__(parent) self.delegate = BackgroundDelegate(self) self.setItemDelegate(self.delegate) self.setShowGrid(False) # self.setAlternatingRowColors(True) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setItemDelegateForColumn(7, RpcVarButtonDelegate(self)) self.model = RpcVarModel(['客户端', '变量名', '类型', '下限', '上限', '当前值', '操作'], self) # 添加代理模型用于搜索过滤 self.proxy = QtCore.QSortFilterProxyModel(self) self.proxy.setSourceModel(self.model) self.setModel(self.proxy) self.header = QHeaderView(Qt.Horizontal, self) self.header.setStretchLastSection(True) self.setHorizontalHeader(self.header) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setupColumnWidths() def setupColumnWidths(self): self.header.setSectionResizeMode(QHeaderView.Stretch) def performSearch(self, searchText): """RPC变量表格搜索接口""" try: # 设置搜索列为变量名列(索引1) self.proxy.setFilterKeyColumn(2) search = QtCore.QRegExp(searchText, QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp) self.proxy.setFilterRegExp(search) return True except Exception as e: print(f"RPC变量搜索失败: {e}") return False