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.
PROFIBUS/UI/BlockParameterManageWidget.py

430 lines
17 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import re
import qtawesome
from PyQt5.QtGui import QPixmap, QPainter, QIcon
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QStyledItemDelegate, QStyle, QComboBox, QMessageBox, QPushButton,QStackedWidget, QLineEdit \
, QVBoxLayout, QHBoxLayout, QWidget, QLabel, QSplitter, QScrollArea, QButtonGroup, QDialog, QRadioButton
from utils.DBModels.DeviceParModels import *
from UI.BlockParameterView import ParmView
from UI.SearchAddressWidget import SearchAddressWidget
from utils.DBModels.DeviceParModels import *
from utils import Globals
from UI.LoadingDataWidget import LoadingDataWidget
from UI.EditAddressWidget import EditAddressWidget
from UI.SoftKeyBoardEdit import *
from model.ProjectModel.BlockManage import BlockManage, BlockType, TBType
class ShowImage(QWidget):
def __init__(self, image_path):
super().__init__()
self.image_path = image_path
self.pixmap = QPixmap(self.image_path)
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(self.rect(), self.pixmap)
class HideTextDelegate(QStyledItemDelegate):
def paint(self, painter, option, index):
# 仅在下拉列表中绘制文本避免在ComboBox显示区域绘制
if option.state & QStyle.State_Enabled:
super().paint(painter, option, index)
def sizeHint(self, option, index):
# 返回原始大小确保下拉列表项不受ComboBox宽度影响
return super().sizeHint(option, index)
class TbCombox(QComboBox):
def __init__(self):
super().__init__()
# self.tbType = tbType
self.initUI()
def initUI(self):
# 创建ComboBox
self.addItems(["压力转换块", "温度转换块", "物位转换块", "流量转换块", 'WIKA液位计','开封流量计'])
self.setEditable(True) # 设置为可编辑以应用样式表隐藏文本
self.setObjectName('tbcombox')
# 设置样式隐藏文本
self.lineEdit().setStyleSheet("color: transparent; border:none; background-color: #f0f0f0")
self.lineEdit().setCursor(Qt.ArrowCursor)
self.lineEdit().setReadOnly(True)
# 设置自定义代理以调整下拉列表行为
self.delegate = HideTextDelegate(self)
self.setItemDelegate(self.delegate)
# 设置ComboBox的固定大小
self.setFixedSize(30, 40)
# 确保下拉列表宽度适应最长项
# max_width = max(self.fontMetrics().width(self.itemText(i)) for i in range(self.count()))
self.view().setMinimumWidth(130)
class DynamicAddBlock(QHBoxLayout):
def __init__(self, blocklist, TbtypeList):
super().__init__()
self.blocklist = blocklist
self.buttonlist = []
self.blockViewlist = []
self.tbtypeList = TbtypeList #存放转换块的各种类型
# print(self.tbtypeList)
self.tbList = ['PressureTranslationBlock', 'TemperatureTranslationBlock', 'LevelTranslationBlock', 'FlowTranslationBlock', 'WiKaLevelTranslationBlock', 'KaiFengFlowTranslationBlock'] #存放四个转换块
self.enumList = [TBType.pressureTB, TBType.tempTB, TBType.levelTB, TBType.flowTB, TBType.wikaLevelTB, TBType.kfFlowTB]
self.initUI()
def initUI(self):
self.setContentsMargins(0, 0, 0, 0)
pbNumber = self.blocklist[0]
tbNumber = self.blocklist[1]
fbNumber = self.blocklist[2]
for i in range(pbNumber):
pblockBtn = QPushButton('物理块')
pblockBtn.setCheckable(True)
# pblockBtn.setFixedSize(90, 43)
pblockBtn.setObjectName("parameBtn")
pblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f'))
# pblockBtn.setCheckable(True)
pblockBtn.clicked.connect(lambda _, pbbtn = pblockBtn: self.switchParameterWidget(pbbtn))
self.addWidget(pblockBtn, 3)
self.buttonlist.append(pblockBtn)
physicalBlockView = ParmView(PhysicalBlock, i, BlockType.PB)
self.blockViewlist.append(physicalBlockView)
if i == 0:
pblockBtn.setChecked(True)
for i in range(fbNumber):
fblockBtn = QPushButton('功能块' + str(i + 1))
# fblockBtn.setFixedSize(90, 43)
fblockBtn.setCheckable(True)
fblockBtn.setObjectName("parameBtn")
fblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f'))
fblockBtn.clicked.connect(lambda _, fbbtn = fblockBtn: self.switchParameterWidget(fbbtn))
self.addWidget(fblockBtn, 3)
self.buttonlist.append(fblockBtn)
aiFunctionBlockView = ParmView(AIFunctionBlock, i, BlockType.FB)
self.blockViewlist.append(aiFunctionBlockView)
for i, tbType in zip(range(tbNumber), self.tbtypeList):
tbwidget = QWidget()
tbwidget.setObjectName('tbwidget')
tblayout = QHBoxLayout()
tbwidget.setLayout(tblayout)
tbcombox = TbCombox()
# print(tbType)
match tbType:
case TBType.pressureTB:
tbcombox.setCurrentIndex(0)
tblockBtn = QPushButton(tbcombox.currentText() + str(i + 1))
case TBType.tempTB:
tbcombox.setCurrentIndex(1)
tblockBtn = QPushButton(tbcombox.currentText() + str(i + 1))
case TBType.levelTB:
# print(2222)
tbcombox.setCurrentIndex(2)
tblockBtn = QPushButton(tbcombox.currentText() + str(i + 1))
case TBType.flowTB:
tbcombox.setCurrentIndex(3)
tblockBtn = QPushButton(tbcombox.currentText() + str(i + 1))
case None:
tbcombox.setCurrentIndex(4)
tblockBtn = QPushButton(tbcombox.currentText() + str(i + 1))
# tbcombox.setCurrentIndex(0)
# tblockBtn = QPushButton('压力转换块' + str(i + 1))
tblockBtn.setObjectName("tbparameBtn")
# tblockBtn.setFixedSize(130, 43)
tblockBtn.setCheckable(True)
tblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f'))
# tblockBtn.clicked.connect(lambda _, tbbtn = tblockBtn: self.switchParameterWidget(tbbtn))
tblockBtn.clicked.connect(lambda _, combox = tbcombox, tbbtn = tblockBtn : self.switchTbtype(combox.currentIndex(), combox, tbbtn))
tbcombox.currentIndexChanged.connect(lambda index, combox = tbcombox, tbbtn = tblockBtn : self.switchTbtype(index, combox, tbbtn))
tblayout.addWidget(tblockBtn, 6)
tblayout.addWidget(tbcombox, 1)
tblayout.setSpacing(0)
self.addWidget(tbwidget, 5)
self.buttonlist.append(tblockBtn)
for tb, enum in zip(self.tbList, self.enumList):
tbBlockView = ParmView(globals()[tb], i, enum)
self.blockViewlist.append(tbBlockView)
self.parameterButtonGroup = QButtonGroup()
self.parameterButtonGroup.setExclusive(True)
for button in self.buttonlist:
self.parameterButtonGroup.addButton(button)
self.parameStackWidget = QStackedWidget()
for view in self.blockViewlist:
self.parameStackWidget.addWidget(view)
def switchParameterWidget(self, buttonType):
for index , button in enumerate(self.buttonlist):
if button == buttonType:
self.parameStackWidget.setCurrentIndex(index)
def switchTbtype(self, index, combox, button):
tbType = combox.itemText(index)
buttonNumber = button.text()[-1]
button.setText(tbType + str(buttonNumber))
if button.isChecked():
stackIndex = (int(self.blocklist[0]) + int(self.blocklist[2]) + index) + (int(buttonNumber) - 1) * 6
print(stackIndex)
self.parameStackWidget.setCurrentIndex(stackIndex)
def deleteLater(self):
while self.count():
item = self.takeAt(0)
widget = item.widget()
if widget:
widget.deleteLater()
layout = item.layout()
if layout:
layout.deleteLater()
if self.parameStackWidget:
while self.parameStackWidget.count():
widget = self.parameStackWidget.widget(0)
self.parameStackWidget.removeWidget(widget)
widget.deleteLater()
self.parameStackWidget.deleteLater()
super().deleteLater()
class BlockParameterManageWidget(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self._isPa = True
self.initUIstat = True
def initUI(self):
self.mainlayout = QVBoxLayout()
self.proTypeLabel = QLabel('PA协议')
self.proTypeLabel.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
self.proTypeLabel.setObjectName('proTypeLabel')
self.proTypeRadioBtn = QRadioButton()
self.proTypeRadioBtn.setObjectName('proTypeRadioBtn')
self.proTypeRadioBtn.toggled.connect(self.changeProType)
self.settingLayout = QHBoxLayout()
self.deviceAddressLabel = QLabel('从站地址')
self.deviceAddressLabel.setObjectName('deviceAddressLabel')
self.deviceAddressEdit = SoftKeyBoardEdit()
self.deviceAddressEdit.returnPressed.connect(self.loadBlackData)
self.deviceAddressEdit.setObjectName("deviceAddressEdit")
self.confirmBtn = QPushButton('连接设备')
self.confirmBtn.setIcon(qtawesome.icon('mdi.connection', color='#1fbb6f'))
self.confirmBtn.clicked.connect(self.loadBlackData)
self.confirmBtn.setObjectName("parameBtn")
self.refershDataBtn = QPushButton('加载数据')
self.refershDataBtn.setIcon(qtawesome.icon('mdi6.reload', color='#1fbb6f'))
self.refershDataBtn.clicked.connect(self.refreshData)
self.refershDataBtn.setObjectName("parameBtn")
# self.deviceAddressSearchBtn = QPushButton('搜索站地址')
# self.deviceAddressSearchBtn.setIcon(qtawesome.icon('fa.search', color='#1fbb6f'))
# self.deviceAddressSearchBtn.clicked.connect(self.searchAddress)
# self.deviceAddressSearchBtn.setObjectName("parameBtn")
self.editAddressBtn = QPushButton('修改站地址')
self.editAddressBtn.setIcon(qtawesome.icon('fa.edit', color='#1fbb6f'))
self.editAddressBtn.clicked.connect(self.editAddress)
self.editAddressBtn.setObjectName("parameBtn")
self.settingLayout.addWidget(self.proTypeLabel, 1)
self.settingLayout.addWidget(self.proTypeRadioBtn, 1)
self.settingLayout.addWidget(self.deviceAddressLabel, 1)
self.settingLayout.addWidget(self.deviceAddressEdit, 1)
self.settingLayout.addWidget(self.confirmBtn, 1)
# self.settingLayout.addWidget(self.deviceAddressSearchBtn, 1)
self.settingLayout.addWidget(self.editAddressBtn, 1)
self.settingLayout.addWidget(self.refershDataBtn, 1)
# self.settingLayout.addLayout(self.blockLayout)
# self.settingLayout.setSpacing(5)
self.scroArea = QScrollArea()
self.scroArea.setObjectName('scroArea')
self.scroArea.horizontalScrollBar().setObjectName('scroBar')
self.splitter = QSplitter()
self.settingLayout.addWidget(self.splitter, 18)
self.mainlayout.addLayout(self.settingLayout,1)
self.widget = ShowImage('Static/pict.png')
self.mainlayout.addWidget(self.widget, 20)
self.setLayout(self.mainlayout)
def loadBlackData(self):
address = self.deviceAddressEdit.text()
# print(address)
if address:
pattern = re.compile(r'^(?:[3-9]|[1-9][0-9]|1[0-1][0-9]|12[0-6])$')
match = pattern.match(address)
else:
reply = QMessageBox.question(self.parent(),
'警告',
"请输入从站地址",
QMessageBox.Yes)
return
if not match:
QMessageBox.warning(self, '提示', '请输入3 - 126。')
return
if self.initUIstat:
try:
self.blockManage = BlockManage(self._isPa, int(address))
except Exception as e:
reply = QMessageBox.question(self.parent(),
'警告',
f"发生错误: {e}",
QMessageBox.Yes)
return
self.splitter.deleteLater()
self.widget.deleteLater()
self.splitter = QSplitter()
Globals.setValue('blockManage', self.blockManage)
blocklist = self.blockManage.getBlockNums()
self.blockLayout = DynamicAddBlock(blocklist, self.blockManage.TBTypeList)
self.scroWidget = QWidget()
self.scroWidget.setObjectName('scroWidget')
self.scroWidget.setLayout(self.blockLayout)
self.scroArea.setWidget(self.scroWidget)
self.settingLayout.addWidget(self.scroArea, 18)
# self.settingLayout.addWidget(self.splitter, 11)
self.mainlayout.addWidget(self.blockLayout.parameStackWidget, 20)
self.initUIstat = False
self.recordAddress = address #记录链接成功的站地址
else:
reply = QMessageBox.question(self, '确定', '确定更换站地址吗?',
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
try:
self.blockManage = BlockManage(self._isPa, int(address))
except Exception as e:
reply = QMessageBox.question(self.parent(),
'警告',
f"发生错误: {e}",
QMessageBox.Yes)
self.deviceAddressEdit.setText(self.recordAddress)
return
self.blockLayout.deleteLater()
self.splitter.deleteLater()
self.splitter = QSplitter()
# self.scroArea.deleteLater()
blocklist = self.blockManage.getBlockNums()
TbtypeList = self.blockManage.TBTypeList
self.blockLayout = DynamicAddBlock(blocklist, TbtypeList)
self.scroWidget = QWidget()
self.scroWidget.setObjectName('scroWidget')
self.scroWidget.setLayout(self.blockLayout)
self.scroArea.setWidget(self.scroWidget)
self.settingLayout.addWidget(self.scroArea, 18)
self.mainlayout.addWidget(self.blockLayout.parameStackWidget, 20)
self.recordAddress = address #记录链接成功的站地址
else:
return
def refreshData(self):
if self.initUIstat:
reply = QMessageBox.question(self.parent(),
'警告',
"请先连接设备",
QMessageBox.Yes)
return
self.loadingDataWidget = LoadingDataWidget()
self.loadingDataWidget.show()
# self.loadingDataWidget.loadData()
blockView = self.blockLayout.parameStackWidget.currentWidget()
model = blockView.model
# model.updateColumn(5, '查询中sdadadsda\r\nsdasdsasasad\r\nasdsadsad...')
# blockView.resizeHeader()
blockType = blockView.blockType
blcokIndex = blockView.blcokIndex
self.blockManage.getBlockValues(blockType = blockType, blockIndex = blcokIndex, callback = self.loadingDataWidget.loadData, callback2 = model.updateValue)
# print(valueList)
# model.updateValue(valueList)
# print(blockType, blcokIndex)
def editAddress(self):
self.editAddressWidget = EditAddressWidget()
# def searchAddress(self):
# self.searchAddressWidget = SearchAddressWidget(self.deviceAddressEdit)
# self.searchAddressWidget.show()
def changeProType(self):
if self.proTypeRadioBtn.isChecked():
self.proTypeLabel.setText('DP协议')
self._isPa = False
else:
self.proTypeLabel.setText('PA协议')
self._isPa = True
self.clearLayout()
def clearLayout(self):
if self.initUIstat:
return
else:
self.blockLayout.deleteLater()
self.splitter.deleteLater()
self.splitter = QSplitter()
self.scroArea.deleteLater()
self.widget = ShowImage('Static/pict.png')
self.mainlayout.addWidget(self.widget, 20)
self.settingLayout.addWidget(self.splitter,18)
self.initUIstat = True