diff --git a/Static/Main.qss b/Static/Main.qss index b9c0488..961cdea 100644 --- a/Static/Main.qss +++ b/Static/Main.qss @@ -101,7 +101,7 @@ QDockWidget::title{ } -QPushButton#startProtocolBtn, QPushButton#switchBtn, QPushButton#switchTouchBtn{ +QPushButton#startProtocolBtn, QPushButton#switchBtn, QPushButton#switchTouchBtn, QPushButton#deviceParameterManageBtn{ font-size: 25px; @@ -111,7 +111,7 @@ QPushButton#startProtocolBtn, QPushButton#switchBtn, QPushButton#switchTouchBtn{ } -QPushButton#startProtocolBtn:hover, QPushButton#switchBtn:hover, QPushButton#switchTouchBtn::hover{ +QPushButton#startProtocolBtn:hover, QPushButton#switchBtn:hover, QPushButton#switchTouchBtn:hover, QPushButton#deviceParameterManageBtn:hover{ font-size: 25px; @@ -125,7 +125,7 @@ QPushButton#startProtocolBtn:hover, QPushButton#switchBtn:hover, QPushButton#swi } -QPushButton#startProtocolBtn:checked, QPushButton#switchBtn:checked, QPushButton#switchTouchBtn:checked{ +QPushButton#startProtocolBtn:checked, QPushButton#switchBtn:checked, QPushButton#switchTouchBtn:checked, QPushButton#deviceParameterManageBtn:checked{ font-size: 25px; diff --git a/Static/PA块信息表.xlsx b/Static/PA块信息表.xlsx new file mode 100644 index 0000000..942cfd1 Binary files /dev/null and b/Static/PA块信息表.xlsx differ diff --git a/Static/modbus映射表.xlsx b/Static/modbus映射表.xlsx new file mode 100644 index 0000000..d0de2fa Binary files /dev/null and b/Static/modbus映射表.xlsx differ diff --git a/UI/AreaTabWidget.py b/UI/AreaTabWidget.py index ffc03d6..66773b1 100644 --- a/UI/AreaTabWidget.py +++ b/UI/AreaTabWidget.py @@ -3,16 +3,16 @@ import sys import json import qtawesome -from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget, QWidget, QVBoxLayout, QLabel, QPushButton, QLayout, \ - QHBoxLayout, QComboBox, QLineEdit, QSpacerItem, QSizePolicy, QGridLayout, QMessageBox, QSplitter, QFrame +from PyQt5.QtWidgets import QApplication, QTabWidget, QWidget, QLabel, QPushButton, \ + QHBoxLayout, QComboBox, QGridLayout, QMessageBox, QSplitter, QFrame from PyQt5.QtGui import QIcon -from PyQt5.QtCore import QSize, Qt +from PyQt5.QtCore import QSize from model.ProjectModel.DeviceManage import Device, DevicesManange from UI.RightAreaWidget import RightAreaWidgets -from utils.DBModels.DeviceModels import DeviceDB + from UI.SoftKeyBoardEdit import SoftKeyBoardEdit diff --git a/UI/BlockParameterManageWidget.py b/UI/BlockParameterManageWidget.py new file mode 100644 index 0000000..6d7e346 --- /dev/null +++ b/UI/BlockParameterManageWidget.py @@ -0,0 +1,112 @@ + +from PyQt5.QtWidgets import QPushButton,QStackedWidget, QLineEdit, QVBoxLayout, QHBoxLayout, QWidget, QLabel, QSplitter + + + +from utils.DBModels.DeviceParModels import * +from UI.BlockParameterView import PressureTBlockView, AIFunctionBlockView, PhysicalBlockView +from UI.SearchAddressWidget import SearchAddressWidget + + + + + + + + + +class BlockParameterManageWidget(QWidget): + def __init__(self): + super().__init__() + self.initUI() + + + def initUI(self): + self.pressureTBlockView = PressureTBlockView() + self.aiFunctionBlockView = AIFunctionBlockView() + self.physicalBlockView = PhysicalBlockView() + + self.mainlayout = QVBoxLayout() + self.parameStackWidget = QStackedWidget() + self.settingLayout = QHBoxLayout() + self.deviceAddressLabel = QLabel('从站地址') + self.deviceAddressEdit = QLineEdit() + + self.confirmBtn = QPushButton('确定') + self.confirmBtn.clicked.connect(self.testUI) + + self.deviceAddressSearchBtn = QPushButton('查找') + self.deviceAddressSearchBtn.clicked.connect(self.searchAddress) + + self.pblockBtn = QPushButton('物理块') + # self.pblockBtn.setCheckable(True) + self.pblockBtn.clicked.connect(lambda: self.switchParameterWidget('pblockBtn')) + + self.fblockBtn = QPushButton('功能块') + self.fblockBtn.clicked.connect(lambda: self.switchParameterWidget('fblockBtn')) + # self.pblockBtn.setCheckable(True) + + self.tblockBtn = QPushButton('转换块') + self.tblockBtn.clicked.connect(lambda: self.switchParameterWidget('tblockBtn')) + # self.tblockBtn.setCheckable(True) + + + 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.pblockBtn, 1) + self.settingLayout.addWidget(self.fblockBtn, 1) + self.settingLayout.addWidget(self.tblockBtn, 1) + self.settingLayout.addWidget(QSplitter(), 18) + + + self.mainlayout.addLayout(self.settingLayout,1) + + self.parameStackWidget.addWidget(self.physicalBlockView) + self.parameStackWidget.addWidget(self.aiFunctionBlockView) + self.parameStackWidget.addWidget(self.pressureTBlockView) + + + + + self.mainlayout.addWidget(self.parameStackWidget, 20) + + # self.proxy = QtCore.QSortFilterProxyModel(self) + # self.parameTableView.proxy = self.proxy + # self.proxy.setSourceModel(self.parameTableView.model) + + # self.parameTableView.setModel(self.proxy) + + # datas = PressureTranslationBlock.getallParame() + # for index, data in enumerate(datas): + # desc = data[2].replace('\r\n', '').replace('\n', '') + # lines = [desc[i:i+50] + "\r\n" for i in range(0, len(desc), 50)] + # # 合并列表为一个字符串,移除最后一个换行符 + # result = "".join(lines).rstrip("\r\n") + # data[2] = result + # data = data + ['', '', ''] + # self.parameTableView.model.append_data(data) + # self.parameTableView.setVerticalHeader(ParamsVHeader(self, self.parameTableView.model.datas)) + + self.setLayout(self.mainlayout) + + def switchParameterWidget(self,blockType): + match blockType: + case "pblockBtn": + self.parameStackWidget.setCurrentIndex(0) + case "fblockBtn": + self.parameStackWidget.setCurrentIndex(1) + case "tblockBtn": + self.parameStackWidget.setCurrentIndex(2) + + def testUI(self): + model = self.parameStackWidget.currentWidget().model + model.updateColumn(5, '查询中...') + + def searchAddress(self): + self.searchAddressWidget = SearchAddressWidget(self.deviceAddressEdit) + self.searchAddressWidget.show() + + + diff --git a/UI/BlockParameterModel.py b/UI/BlockParameterModel.py new file mode 100644 index 0000000..27b4241 --- /dev/null +++ b/UI/BlockParameterModel.py @@ -0,0 +1,210 @@ +import typing +import re +import qtawesome +from PyQt5 import QtGui,QtCore,QtWidgets +from PyQt5.QtCore import QAbstractTableModel, QModelIndex, Qt, QVariant, QSize +from PyQt5.QtWidgets import QItemDelegate, QHBoxLayout, QWidget, QPushButton, QMessageBox, QLineEdit, QComboBox, QStyledItemDelegate + + + + +class VarTableModel(QAbstractTableModel): + ''' 变量表模型类''' + def __init__(self, header, data: list, table = None): + ''' + header : 表头变量 + data : 表格内容 + table : 缺省参数 + ''' + QAbstractTableModel.__init__(self, parent=None) + self.header = header + self.datas = data + self.checkList = ['Unchecked'] * len(self.datas) + self.supportedDragActions() + self.table = table + self.editableList = [] # 表格中可编辑项 + + + + def append_data(self, x): + + self.datas.append(x) + self.checkList = ['Unchecked'] * len(self.datas) + self.table.proxy.invalidate() + # self.layoutChanged.emit() + + def insert_data(self, x, index): + self.datas.insert(index, x) + self.checkList = ['Unchecked'] * len(self.datas) + self.table.proxy.invalidate() + + def updateColumn(self, column, value): + if column < 0 or column >= self.columnCount(): + print("列索引超出范围") + return + for row in range(self.rowCount()): + self.datas[row][column] = value + self.table.proxy.invalidate() + # self.layoutChanged.emit() # 通知视图数据已更改 + # self.dataChanged.emit() + + def remove_row(self, row): + self.datas.pop(row) + self.checkList = ['UnChecked'] * len(self.datas) + self.table.proxy.invalidate() + + def rowCount(self, parent: QModelIndex = ...) -> int: + if len(self.datas) > 0: + return len(self.datas) + return 0 + + def columnCount(self, parent: QModelIndex = ...) -> int: + return len(self.header) + + def data(self, QModelIndex, role=None): + # print(Qt.__dict__.items()) + if role == Qt.TextAlignmentRole: + return Qt.AlignCenter + if not QModelIndex.isValid(): + print("行或者列有问题") + return QVariant() + + if role == Qt.TextColorRole: + return QtGui.QColor('#1A1A1A') + + if role == Qt.DisplayRole or role == Qt.EditRole: + if QModelIndex.row() in self.editableList or 'w' in self.datas[QModelIndex.row()][4]: + return self.datas[QModelIndex.row()][QModelIndex.column()] + if role != Qt.DisplayRole: + return QVariant() + + + return self.datas[QModelIndex.row()][QModelIndex.column()] + + def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> typing.Any: # 表头 + if role != Qt.DisplayRole: + return None + + if role == Qt.SizeHintRole: + # print(self.datas[QModelIndex.row()][QModelIndex.column()].find('\r\n')) + return QSize(500, 500) + + if orientation == Qt.Horizontal: + return self.header[section] + + # if orientation == Qt.Vertical: + # return str(section + 1) + + def setData(self, index, value, role): + row = index.row() + col = index.column() + if role == Qt.EditRole: + self.datas[row][col] = value + return True + return True + + def flags(self, index): + # if index.column() == 0: + # return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable + if index.row() in self.editableList and index.column() or index.column() == 6: + return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEditable + + + if 'w' in self.datas[index.row()][4] and index.column() == 5: + return Qt.ItemIsEnabled | Qt.ItemIsEditable + + return Qt.ItemIsEnabled + + def dragMoveEvent(self, event): + event.setDropAction(QtCore.Qt.MoveAction) + event.accept() + + def moveRow(self, sourceParent: QModelIndex, sourceRow: int, destinationParent: QModelIndex, + destinationChild: int) -> bool: + if self.datas[destinationChild] == self.datas[sourceRow]: + return + self.datas[sourceRow], self.datas[destinationChild] = self.datas[destinationChild], self.datas[sourceRow] + self.table.proxy.invalidate() + + +class VarButtonDelegate(QItemDelegate): + """该类用于向单元格中添加按钮 任务表格""" + def __init__(self, parent=None): + super(VarButtonDelegate, self).__init__(parent) + + def paint(self, painter, option, index): + if not self.parent().indexWidget(index): + button1 = QPushButton( + qtawesome.icon('fa.play', color='#1fbb6f'), + "", + self.parent() + ) + + if 'w' not in self.parent().model.datas[index.row()][4]: + return + + + button1.index = [index.row(), index.column()] + + parameEditline = QLineEdit() + + boxLayout = QHBoxLayout() + boxLayout.addWidget(parameEditline) + boxLayout.addWidget(button1) + + button1.clicked.connect(lambda: self.startAction(parameEditline)) + + boxLayout.setContentsMargins(2, 0, 0, 2) + boxLayout.setAlignment(Qt.AlignCenter) + widget = QWidget() + widget.setLayout(boxLayout) + self.parent().setIndexWidget( + index, + widget + ) + + + def startAction(self, parameEditline): + sender = self.sender() + model = self.parent().model + # value = model.datas[sender.index[0]][sender.index[1]] + value = parameEditline.text() + pattern = re.compile(r'[^0-9\.-]+') + if not value or re.findall(pattern, str(value)): + reply = QMessageBox.question(self.parent(), + '警告', + "请输入强制值或数字", + QMessageBox.Yes) + return + + +class ComboBoxDelegate(QStyledItemDelegate): + def __init__(self, parent=None): + super(ComboBoxDelegate, self).__init__(parent) + + def createEditor(self, parent, option, index): + # 仅在第二列第二行创建编辑器 + if index.row() == 5 and index.column() == 5: + comboBox = QComboBox(parent) + comboBox.addItems(["非服务", "手动初始化", "本地超驰", '手动', '自动', '级联', '远程级联', '远程输出']) + return comboBox + else: + return super().createEditor(parent, option, index) + + def setEditorData(self, editor, index): + if index.row() == 5 and index.column() == 5: + # value = index.model().data(index, Qt.EditRole) + value = "非服务" + if value: + editor.setCurrentText(value) + else: + super().setEditorData(editor, index) + + def setModelData(self, editor, model, index): + if index.row() == 5 and index.column() == 5: + model.setData(index, editor.currentText(), Qt.EditRole) + else: + super().setModelData(editor, model, index) + + def updateEditorGeometry(self, editor, option, index): + editor.setGeometry(option.rect) diff --git a/UI/BlockParameterView.py b/UI/BlockParameterView.py new file mode 100644 index 0000000..14e45ee --- /dev/null +++ b/UI/BlockParameterView.py @@ -0,0 +1,112 @@ +from PyQt5 import QtCore +from PyQt5.QtGui import QTextDocument +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QHeaderView, QAbstractItemView, QTableView, QWidget, QDesktopWidget +from UI.BlockParameterModel import VarTableModel, VarButtonDelegate, ComboBoxDelegate + +from utils.DBModels.DeviceParModels import * + +class ParamsVHeader(QHeaderView): + def __init__(self, parent, datas): + super().__init__(Qt.Vertical, parent) + self.datas = datas + + def resizeEvent(self, event): + """Resize table as a whole, need this to enable resizing""" + super(QHeaderView, self).resizeEvent(event) + + for index, content in enumerate(self.datas): + self.setSectionResizeMode(index, QHeaderView.Fixed) + self.resizeSection(index, 50 * (content[2].count('\r\n') + 1)) + + return + + +class VarTableView(QTableView): + def __init__(self, parent=None): + super(VarTableView, self).__init__(parent) + self.parent = parent + self.setHeader() + self.setupUi() + + def setHeader(self): + self.setItemDelegateForColumn(6, VarButtonDelegate(self)) + self.setItemDelegateForColumn(5, ComboBoxDelegate(self)) + + self.model = VarTableModel(['相对索引', '参数名', '描述', '数据类型', '访问', '当前值', '输入值'], [], table = self) + + def setupUi(self): + self.setShowGrid(True) + self.setAlternatingRowColors(True) + self.setSelectionBehavior(QAbstractItemView.SelectRows) + + + #设置单元格宽度比例 + self.header = self.horizontalHeader() + self.header.setSectionResizeMode(QHeaderView.Interactive) + self.header.setStretchLastSection(True) + + self.proxy = QtCore.QSortFilterProxyModel(self) + # # self.parameTableView.proxy = self.proxy + self.proxy.setSourceModel(self.model) + + self.setModel(self.proxy) + self.setCustomColumnWidths([1, 3, 9, 2, 2, 2, 2]) + + + # self.header.checkClicked.connect(self.model.headerClick) + # self.setHorizontalHeader(self.header) + # self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + + # self.header.setSectionResizeMode(0, QHeaderView.Fixed) + # self.header.resizeSection(0, 70) + def setCustomColumnWidths(self, ratios): + # 计算总比例 + totalRatio = sum(ratios) + # 获取窗口宽度 + screen = QDesktopWidget().screenGeometry() + width = screen.width() - 80 + + # 根据比例设置每列的宽度 + for i, ratio in enumerate(ratios): + columnWidth = int(width * (ratio / totalRatio)) + self.setColumnWidth(i, columnWidth) + + + + +class PressureTBlockView(VarTableView): + def __init__(self, datas = None): + super().__init__() + self.datas = datas + self.initUI() + + + def initUI(self): + if not self.datas: + self.datas = PressureTranslationBlock.getallParame() + for index, data in enumerate(self.datas): + desc = data[2].replace('\r\n', '').replace('\n', '') + lines = [desc[i:i+50] + "\r\n" for i in range(0, len(desc), 50)] + # 合并列表为一个字符串,移除最后一个换行符 + result = "".join(lines).rstrip("\r\n") + data[2] = result + data = data + ['', '', ''] + self.model.append_data(data) + self.setVerticalHeader(ParamsVHeader(self, self.model.datas)) + +class AIFunctionBlockView(PressureTBlockView): + def __init__(self): + self.datas = AIFunctionBlock.getallParame() + super().__init__(self.datas) + + + + +class PhysicalBlockView(PressureTBlockView): + def __init__(self): + self.datas = PhysicalBlock.getallParame() + super().__init__(self.datas) + + + \ No newline at end of file diff --git a/UI/DeviceDialogWidget.py b/UI/DeviceDialogWidget.py index 6f64af5..26bfe7b 100644 --- a/UI/DeviceDialogWidget.py +++ b/UI/DeviceDialogWidget.py @@ -27,7 +27,7 @@ from utils.DBModels.DeviceModels import DeviceDB class DeviceDialog(QDialog): BORDER_WIDTH = 5 #设圆角 - def __init__(self,dataTypeAndModel,parent=None): + def __init__(self,dataTypeAndModel = None, parent=None): super().__init__(parent) self.dataTypeAndModel = dataTypeAndModel self.initUI() diff --git a/UI/DeviceWidget.py b/UI/DeviceWidget.py index 34fdf9c..b808487 100644 --- a/UI/DeviceWidget.py +++ b/UI/DeviceWidget.py @@ -12,7 +12,7 @@ from utils.DBModels.BaseModel import * from UI.AreaTabWidget import AreaTabWidget from utils.DBModels.DeviceModels import DeviceDB from model.ProjectModel.DeviceManage import DevicesManange -from UI.DeviceDialogWidget import DeviceDialog + from PyQt5.QtWidgets import QApplication, QStyleOptionTab, QTabBar, QWidget from PyQt5.QtGui import QPainter, QPen, QColor, QPainterPath, QPolygonF, QFontMetrics, QTextOption, QFont diff --git a/UI/MainWindow.py b/UI/MainWindow.py index 86495e6..5c91515 100644 --- a/UI/MainWindow.py +++ b/UI/MainWindow.py @@ -1,4 +1,4 @@ -import os + import sys import time import win32con @@ -7,7 +7,7 @@ import win32process import subprocess import qtawesome -from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow, QDockWidget, QToolBar, QAction, QTabWidget, QGridLayout, QWidget, QHBoxLayout, QStackedWidget\ +from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow, QDockWidget, QWidget, QHBoxLayout, QStackedWidget\ ,QVBoxLayout, QProgressBar, QLabel from PyQt5.QtCore import Qt, QTimer, QSize from PyQt5.QtGui import QIcon, QWindow, QPixmap @@ -15,17 +15,20 @@ from utils.DBModels.BaseModel import * from model.ClientModel.Client import Client from UI.DeviceWidget import DeviceTab from model.ProjectModel.DeviceManage import DevicesManange +from utils.DBModels.InitParameterDB import InitParameterDB from protocol.BatterySerial.BatteryProtocol import BatteryManange +from UI.BlockParameterManageWidget import BlockParameterManageWidget import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QProgressBar, QVBoxLayout, QWidget -from PyQt5.QtCore import Qt, QRect, QSize -from PyQt5.QtGui import QPainter, QFont, QColor - +from PyQt5.QtCore import Qt, QSize +from PyQt5.QtGui import QPainter, QFont from utils import Globals + + class CustomProgressBar(QProgressBar): def __init__(self, parent=None): super().__init__(parent) @@ -68,9 +71,11 @@ def getHwndByPid(pid): class MainWindow(QWidget): def __init__(self): super().__init__() + InitParameterDB() self.setObjectName("MainWindow") self.devicesManange = DevicesManange() self.batteryManange = BatteryManange() + self.blockParameterManageWidget = BlockParameterManageWidget() self.process = None self.initUI() @@ -103,6 +108,13 @@ class MainWindow(QWidget): self.switchBtn.setCheckable(True) self.switchBtn.clicked.connect(self.switchWidget) + self.deviceParameterManageBtn = QPushButton('设备参数管理') + self.deviceParameterManageBtn.setObjectName('deviceParameterManageBtn') + self.deviceParameterManageBtn.setIcon(qtawesome.icon('fa.gears', color='#1fbb6f')) + self.deviceParameterManageBtn.setIconSize(QSize(25, 25)) + self.deviceParameterManageBtn.setCheckable(True) + self.deviceParameterManageBtn.clicked.connect(self.switchDeviceParManageWidget) + self.batteryProBar = CustomProgressBar() self.batteryProBar.setRange(0, 100) @@ -112,7 +124,7 @@ class MainWindow(QWidget): self.switchTouchBtn = QPushButton("触控模式") self.switchTouchBtn.setIconSize(QSize(25, 25)) self.switchTouchBtn.setObjectName('switchTouchBtn') - self.switchTouchBtn.setIcon(qtawesome.icon('fa.keyboard-o', color='#1fbb6f')) + self.switchTouchBtn.setIcon(qtawesome.icon('fa.hand-pointer-o', color='#1fbb6f')) self.switchTouchBtn.clicked.connect(self.switchTouchMode) self.switchTouchBtn.setCheckable(True) @@ -140,6 +152,7 @@ class MainWindow(QWidget): toolbarLayout.addWidget(self.startProtocolBtn, 1) toolbarLayout.addWidget(self.switchBtn, 1) toolbarLayout.addWidget(self.switchTouchBtn, 1) + toolbarLayout.addWidget(self.deviceParameterManageBtn, 1) toolbarLayout.addWidget(QWidget(), 20) # toolbarLayout.addWidget(QLabel('电量:'), 1) toolbarLayout.addWidget(self.batteryProBar, 1) @@ -177,6 +190,7 @@ class MainWindow(QWidget): self.stackWidget.addWidget(self.upperWidget) self.stackWidget.addWidget(QWidget()) + self.stackWidget.addWidget(self.blockParameterManageWidget) self.mainLayout = QVBoxLayout(self) self.mainLayout.addLayout(toolbarLayout, 1) @@ -250,9 +264,10 @@ class MainWindow(QWidget): # self.capacity = capacity # mAH # self.cappercent = cappercent # 百分比% # self.state = state # 充放电状态 - result = self.batteryManange.readBatteryInfo() - self.batteryProBar.setValue(result.cappercent) - self.batteryStateLabel.setText(result.chargingStatus) + pass + # result = self.batteryManange.readBatteryInfo() + # self.batteryProBar.setValue(result.cappercent) + # self.batteryStateLabel.setText(result.chargingStatus) @@ -277,6 +292,17 @@ class MainWindow(QWidget): self.switchBtn.setText('通讯组态') # self.switchBtn.setIcon(QIcon(':/static/newH.png')) + + def switchDeviceParManageWidget(self): + if self.deviceParameterManageBtn.isChecked(): + self.stackWidget.setCurrentIndex(2) + self.deviceParameterManageBtn.setText('变量读写') + self.deviceParameterManageBtn.setIcon(qtawesome.icon('fa.pencil-square-o', color='#1fbb6f')) + + else: + self.stackWidget.setCurrentIndex(0) + self.deviceParameterManageBtn.setText('设备参数管理') + self.deviceParameterManageBtn.setIcon(qtawesome.icon('fa.gears', color='#1fbb6f')) def showLowerWidget(self, process): @@ -310,9 +336,11 @@ class MainWindow(QWidget): def switchTouchMode(self): if self.switchTouchBtn.isChecked(): Globals.setValue('_touchMode', 1) + self.switchTouchBtn.setIcon(qtawesome.icon('fa.keyboard-o', color='#1fbb6f')) self.switchTouchBtn.setText('键盘模式') else: Globals.setValue('_touchMode', 0) + self.switchTouchBtn.setIcon(qtawesome.icon('fa.hand-pointer-o', color='#1fbb6f')) self.switchTouchBtn.setText('触控模式') def toggleMaximize(self): diff --git a/UI/RightAreaWidget.py b/UI/RightAreaWidget.py index 0504cc3..628900e 100644 --- a/UI/RightAreaWidget.py +++ b/UI/RightAreaWidget.py @@ -1,8 +1,7 @@ import re -from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget, QWidget, QVBoxLayout, QLabel, QPushButton, QLayout, \ - QHBoxLayout, QComboBox, QLineEdit, QSpacerItem, QSizePolicy, QGridLayout, QMessageBox, QSplitter, QFrame, QRadioButton -from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, \ + QHBoxLayout, QMessageBox, QSplitter, QRadioButton from UI.SoftKeyBoardEdit import SoftKeyBoardEdit diff --git a/UI/SearchAddressWidget.py b/UI/SearchAddressWidget.py new file mode 100644 index 0000000..511608a --- /dev/null +++ b/UI/SearchAddressWidget.py @@ -0,0 +1,80 @@ +from UI.DeviceDialogWidget import DeviceDialog +import sys +import re +import random +from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt5.QtCore import Qt, QTimer +from PyQt5.Qt import * + +from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, \ + QApplication, QLineEdit, QWidget, QTableWidget, QSplitter,QVBoxLayout,QPushButton, QProgressBar, QTableWidgetItem, QMessageBox +from PyQt5.QtWidgets import QDialog + +class SearchAddressWidget(QWidget): + def __init__(self, deviceAddressEdit): + super().__init__() + self.selected_value = None + self.deviceAddressEdit = deviceAddressEdit + self.initUI() + + def initUI(self): + self.resize(800, 500) + self.setObjectName('deviceDialog') + self.addressTabWidget = QTableWidget() + self.addressTabWidget.setRowCount(10) + self.addressTabWidget.setColumnCount(1) + + self.addressTabWidget.setShowGrid(False) #隐藏网格线 + self.addressTabWidget.horizontalHeader().setVisible(False) # 隐藏水平表头 + self.addressTabWidget.verticalHeader().setVisible(False) # 隐藏垂直表头 + self.header = self.addressTabWidget.horizontalHeader() + self.header.setStretchLastSection(True) #设置最后一列顶格 + self.addressTabWidget.setFocusPolicy(Qt.NoFocus) #取消选中焦点,去掉虚线框 + self.addressTabWidget.setEditTriggers(QTableWidget.NoEditTriggers) + self.addressTabWidget.cellClicked.connect(self.onCellClicked) + self.addressTabWidget.cellDoubleClicked.connect(lambda row, column: self.onCellClicked(row, column, True)) + + self.item = QTableWidgetItem('16') + self.addressTabWidget.setItem(0, 0, self.item) + + self.mainlayout = QVBoxLayout() + self.progressBar = QProgressBar(self) + self.bottomLayout = QHBoxLayout() + + self.confirmBtn = QPushButton('确定') + self.confirmBtn.clicked.connect(self.onConfirm) + + self.cancelBtn = QPushButton('取消') + + self.bottomLayout.addWidget(self.confirmBtn) + self.bottomLayout.addWidget(QSplitter()) + self.bottomLayout.addWidget(self.cancelBtn) + + self.mainlayout.addWidget(self.progressBar) + self.mainlayout.addWidget(self.addressTabWidget) + self.mainlayout.addLayout(self.bottomLayout) + + self.setLayout(self.mainlayout) + self.setWindowTitle('从站地址查找') + + self.timer = QTimer() + self.timer.timeout.connect(self.updateProgress) + self.timer.start(500) + + def updateProgress(self): + # 模拟一个任务,逐步更新进度条 + self.progressBar.setValue(int(125 * (100/125))) + # QApplication.processEvents() # 确保UI及时更新 + # QTimer.singleShot(100, lambda: None) # 暂停一小段时间,模拟任务执行时间 + + def onCellClicked(self, row, column, double = False): + item = self.addressTabWidget.item(row, column) + if item: + self.address = item.text() + if double: + self.onConfirm() + + def onConfirm(self): + self.deviceAddressEdit.setText(self.address) + self.close() + diff --git a/bin.py b/bin.py index 13da3ba..d2a692a 100644 --- a/bin.py +++ b/bin.py @@ -5,6 +5,7 @@ from model.ClientModel.Client import Client from utils import Globals + import time import sys @@ -30,9 +31,10 @@ if __name__ == '__main__': app.setStyle(QStyleFactory.create('windowsvisio')) from Static.Png import qInitResources qInitResources() - from Static.QSS import qInitResources - qInitResources() - app.setStyleSheet(CommonHelper.readQrcQss('static/Main.qss') + CommonHelper.readQrcQss('static/Area.qss')) + # from Static.QSS import qInitResources + # qInitResources() + # app.setStyleSheet(CommonHelper.readQrcQss('static/Main.qss') + CommonHelper.readQrcQss('static/Area.qss')) + app.setStyleSheet(CommonHelper.readLocalQss('Static/Main.qss') + CommonHelper.readLocalQss('Static/Area.qss')) Globals._init() Client.initDB() window = MainWindow() diff --git a/model/ClientModel/Client.py b/model/ClientModel/Client.py index 44c662a..f18e294 100644 --- a/model/ClientModel/Client.py +++ b/model/ClientModel/Client.py @@ -3,6 +3,7 @@ import sys from peewee import * from utils.DBModels.BaseModel import * from utils.DBModels.DeviceModels import * +from utils.DBModels.DeviceParModels import * class Client(object): def __init__(self): super(Client, self).__init__() @@ -17,6 +18,6 @@ class Client(object): else: self.deviceDB = SqliteDatabase(dbPath) client_proxy.initialize(self.deviceDB) - modelsArr = [DeviceDB] + modelsArr = [DeviceDB, PressureTranslationBlock, PhysicalBlock, AIFunctionBlock] self.deviceDB.connect() self.deviceDB.create_tables(modelsArr, safe = True) diff --git a/protocol/BatterySerial/BatteryProtocol.py b/protocol/BatterySerial/BatteryProtocol.py index deb0b1f..6d56f0b 100644 --- a/protocol/BatterySerial/BatteryProtocol.py +++ b/protocol/BatterySerial/BatteryProtocol.py @@ -65,5 +65,6 @@ class BatteryManange(): return result def close(self): - self.ser.close() + pass + # self.ser.close() diff --git a/utils/DBModels/DeviceModels.py b/utils/DBModels/DeviceModels.py index a3bcb17..0df941d 100644 --- a/utils/DBModels/DeviceModels.py +++ b/utils/DBModels/DeviceModels.py @@ -62,8 +62,6 @@ class DeviceDB(BaseModel): # print(self.createTime) self.save() - - diff --git a/utils/DBModels/DeviceParModels.py b/utils/DBModels/DeviceParModels.py new file mode 100644 index 0000000..b0c7fae --- /dev/null +++ b/utils/DBModels/DeviceParModels.py @@ -0,0 +1,89 @@ +import sys +import os +import datetime +from peewee import * +import json +import pandas as pd + +from utils.DBModels.BaseModel import BaseModel + +sys.path.append('../') +sys.path.append('../../../') + + + + +class PressureTranslationBlock(BaseModel): + index = CharField() + paramName = CharField() + objectType = CharField() + dataType = CharField() + saveType = CharField() + dataSize = CharField() + accessType = CharField() + transferType = CharField() + description = CharField() + createTime = CharField() + + # 查询设备是否存在 + @classmethod + def getallParame(cls): + devices = cls.get_all() + if devices is 'error': + return + l = [] + for x in devices: + l.append([x.index, x.paramName, x.description, x.dataType, x.accessType]) + return l + + @classmethod + def getByName(cls, paramName): + try: + return cls.get(cls.paramName == str(paramName)) + except Exception as e: + return + + def addParame(self, index, paramName, objectType, dataType, saveType, dataSize, accessType, transferType, description): + self.index = index + self.paramName = paramName + self.objectType = objectType + self.dataType = dataType + self.saveType = saveType + self.dataSize = dataSize + self.accessType = accessType + self.transferType = transferType + self.description = description + self.createTime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S') + # print(self.createTime) + self.save() + + + + +class PhysicalBlock(PressureTranslationBlock): + index = CharField() + paramName = CharField() + objectType = CharField() + dataType = CharField() + saveType = CharField() + dataSize = CharField() + accessType = CharField() + transferType = CharField() + description = CharField() + createTime = CharField() + + + +class AIFunctionBlock(PressureTranslationBlock): + index = CharField() + paramName = CharField() + objectType = CharField() + dataType = CharField() + saveType = CharField() + dataSize = CharField() + accessType = CharField() + transferType = CharField() + description = CharField() + createTime = CharField() + + \ No newline at end of file diff --git a/utils/DBModels/InitParameterDB.py b/utils/DBModels/InitParameterDB.py new file mode 100644 index 0000000..f584320 --- /dev/null +++ b/utils/DBModels/InitParameterDB.py @@ -0,0 +1,19 @@ +from utils.DBModels.DeviceParModels import * + + +class InitParameterDB(): + def __init__(self) -> None: + self.writeParameter() + + def writeParameter(self) -> None: + blockNames = pd.ExcelFile('static/PA块信息表.xlsx').sheet_names + for blockName in blockNames: + parameters = pd.read_excel('static/PA块信息表.xlsx', sheet_name=str(blockName)) + + for index, row in parameters.iterrows(): + parameter = row.values + clsblockName = globals()[blockName]() #通过excel的sheet名字获取对应的数据库函数 + if not clsblockName.getByName(parameter[1]): + clsblockName.addParame(index = parameter[0], paramName = parameter[1], objectType = parameter[2], dataType = parameter[3], + saveType = parameter[4], dataSize = parameter[5], accessType = parameter[6], transferType = parameter[7], description = parameter[8]) + \ No newline at end of file