diff --git a/Static/Main.qss b/Static/Main.qss index a75fd34..fdb14a4 100644 --- a/Static/Main.qss +++ b/Static/Main.qss @@ -156,3 +156,32 @@ QTabWidget#areaTabWidget{ } + +QLabel#batteryLabel{ + + font-size: 20px; + + font: bold; + + border: none; + +} + +QProgressBar { + + border: 2px solid grey; + + border-radius: 5px; + + text-align: center; + + color: white; +} + +QProgressBar::chunk { + + background-color: green; + + width: 20px; + +} diff --git a/UI/MainWindow.py b/UI/MainWindow.py index 4b1efb7..403e052 100644 --- a/UI/MainWindow.py +++ b/UI/MainWindow.py @@ -8,7 +8,7 @@ import subprocess import qtawesome from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow, QDockWidget, QToolBar, QAction, QTabWidget, QGridLayout, QWidget, QHBoxLayout, QStackedWidget\ - ,QVBoxLayout + ,QVBoxLayout, QProgressBar, QLabel from PyQt5.QtCore import Qt, QTimer, QSize from PyQt5.QtGui import QIcon, QWindow from utils.DBModels.BaseModel import * @@ -16,6 +16,29 @@ from model.ClientModel.Client import Client from UI.DeviceWidget import DeviceTab from model.ProjectModel.DeviceManage import DevicesManange +from protocol.BatterySerial.BatteryProtocol import BatteryManange + +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 + +class CustomProgressBar(QProgressBar): + def __init__(self, parent=None): + super().__init__(parent) + self.setTextVisible(False) + self.setFont(QFont("Arial", 10)) # 设置字体大小和类型 + + + def paintEvent(self, event): + super().paintEvent(event) + painter = QPainter(self) + value = self.value() + percentage = round(value / self.maximum() * 100, 1) + text = f"剩余电量{percentage}%" + painter.drawText(self.rect(), Qt.AlignCenter, text) + + def getHwndByPid(pid): def callback(hwnd, hwnds): @@ -25,8 +48,15 @@ def getHwndByPid(pid): hwnds.append(hwnd) hwnds = [] - win32gui.EnumWindows(callback, hwnds) - return hwnds[0] + # win32gui.EnumWindows(callback, hwnds) + while True: + win32gui.EnumWindows(callback, hwnds) + if hwnds: + return hwnds[0] + # 如果没有找到窗口,则等待一段时间再尝试 + time.sleep(0.1) + # return hwnds + # return hwnds[0] class CommonHelper: def __init__(self): @@ -43,6 +73,7 @@ class MainWindow(QWidget): super().__init__() self.setObjectName("MainWindow") self.devicesManange = DevicesManange() + self.batteryManange = BatteryManange() self.process = None self.initUI() @@ -50,6 +81,10 @@ class MainWindow(QWidget): self.protocolTimer = QTimer() self.protocolTimer.timeout.connect(self.readValues) + self.batteryTimer = QTimer() + self.batteryTimer.timeout.connect(self.refreshProgressBar) + self.batteryTimer.start(3000) + # self.toolbarWidget = QWidget() # self.addToolBar(Qt.LeftToolBarArea, self.toolbar) @@ -71,9 +106,18 @@ class MainWindow(QWidget): self.switchBtn.setCheckable(True) self.switchBtn.clicked.connect(self.switchWidget) + self.batteryProBar = CustomProgressBar() + self.batteryProBar.setRange(0, 100) + + self.batteryStateLabel = QLabel() + self.batteryStateLabel.setObjectName('batteryLabel') + toolbarLayout.addWidget(self.startProtocolBtn, 1) toolbarLayout.addWidget(self.switchBtn, 1) toolbarLayout.addWidget(QWidget(), 20) + # toolbarLayout.addWidget(QLabel('电量:'), 1) + toolbarLayout.addWidget(self.batteryProBar, 1) + toolbarLayout.addWidget(self.batteryStateLabel, 1) toolbarLayout.setSpacing(20) toolbarLayout.setContentsMargins(0, 0, 0, 0) @@ -113,6 +157,8 @@ class MainWindow(QWidget): self.setWindowIcon(QIcon('Static/zhjt.ico')) self.setWindowTitle("PROFIBUS") + + self.refreshProgressBar() # self.resize(800, 600) # self.showMaximized() @@ -161,6 +207,19 @@ class MainWindow(QWidget): buttonlayoutWidget.readValues(curIndex = areacurindex) # except Exception as e: # print(e) + + def refreshProgressBar(self): + # self.temp = temp / 10 if temp > -3276.8 else float('nan') # 假设温度值需要除以10得到实际℃数 + # self.current = current # mA + # self.volt = volt # mV + # self.remaintime = remaintime # 分钟 + # self.capacity = capacity # mAH + # self.cappercent = cappercent # 百分比% + # self.state = state # 充放电状态 + result = self.batteryManange.readBatteryInfo() + self.batteryProBar.setValue(result.cappercent) + self.batteryStateLabel.setText(result.chargingStatus) + def switchWidget(self): @@ -211,6 +270,7 @@ class MainWindow(QWidget): def closeEvent(self, event): if self.process: self.process.kill() + self.batteryManange.close() if __name__ == '__main__': app = QApplication(sys.argv) diff --git a/protocol/BatterySerial/BatteryProtocol.py b/protocol/BatterySerial/BatteryProtocol.py new file mode 100644 index 0000000..deb0b1f --- /dev/null +++ b/protocol/BatterySerial/BatteryProtocol.py @@ -0,0 +1,69 @@ +import serial +import struct + +# 定义电池状态常量 +BATSTATE_CHARGE_COMPLETE = 0x01 +BATSTATE_CHARGE_NOW = 0x02 +BATSTATE_CHARGE_LEARN = 0x10 +BATSTATE_DISCHAR_NOW = 0x04 + +# 定义TagResult结构体对应的Python类 +class TagResult: + def __init__(self, data): + fmt = ' -3276.8 else float('nan') # 假设温度值需要除以10得到实际℃数 + self.current = current # mA + self.volt = volt # mV + self.remaintime = remaintime # 分钟 + self.capacity = capacity # mAH + self.cappercent = cappercent # 百分比% + self.state = state # 充放电状态 + + @property + def chargingStatus(self): + statusString = "" + if self.state & BATSTATE_DISCHAR_NOW: + statusString = f"剩余使用时间约:{self.remaintime}分钟" + if self.state & BATSTATE_CHARGE_LEARN: + statusString += ",现在插入充电器可执行充电校准" + + elif (self.state & BATSTATE_CHARGE_NOW) or (self.state & BATSTATE_CHARGE_COMPLETE): + if self.state & BATSTATE_CHARGE_NOW: + statusString = "充电中" + else: + statusString = "充电完成" + if self.state & BATSTATE_CHARGE_LEARN: + statusString += ",正在执行充电校准" + + return statusString + +class BatteryManange(): + + def __init__(self): + self.port = 'COM2' # 替换为实际的串口号 + self.baudRate = 9600 + try: + self.ser = serial.Serial(self.port, self.baudRate) + except: + pass + + def readBatteryInfo(self): + command = b'\xAA\xFF\x55\xFF\x01\x80\xAA\xEE\x55\xEE' + self.ser.write(command) + response = self.ser.read(26) + + # 检查包头和包尾是否正确 + if not (response.startswith(b'\xAA\xFF\x55\xFF') and response.endswith(b'\xAA\xEE\x55\xEE')): + raise ValueError("无效的包头或包尾") + + contentData = response[4:22] + # 创建TagResult对象并解析电池信息 + result = TagResult(contentData) + # print(result.chargingStatus) + return result + + def close(self): + self.ser.close() +