from PyQt5.QtWidgets import QWidget, QVBoxLayout from PyQt5.QtGui import QPainter, QColor, QBrush, QFont from PyQt5.QtCore import Qt class BatteryWidget(QWidget): def __init__(self, total_voltage=24.4): super().__init__() self.total_voltage = total_voltage self.soc = self.get_soc_from_total_voltage(self.total_voltage) def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) # 开启抗锯齿 # 绘制电池轮廓 width, height = 80, 40 # 电池图标的宽度和高度 x, y = (self.width() - width) // 2, 20 # 图标垂直居中 painter.setPen(Qt.black) # 设置边框颜色为黑色 painter.setBrush(QColor(200, 200, 200)) # 设置背景颜色为灰色 painter.drawRoundedRect(x, y, width, height, 3, 3) # 绘制圆角矩形 # 绘制电池正极 painter.setBrush(QColor(0, 0, 0)) # 设置正极颜色为黑色 painter.drawRect(x + width, y + height // 4, width // 10, height // 2) # 根据电量百分比填充电池 fill_height = int(height * 0.8) # 留出上下边距 fill_width = int((width - 4) * (self.soc / 100)) # 根据 SoC 缩放填充宽度 fill_color = self.get_battery_color(self.soc) # 获取电量对应的颜色 painter.setBrush(QBrush(QColor(*fill_color))) painter.drawRect(x + 2, y + (height - fill_height) // 2, fill_width, fill_height) # 绘制百分比文字 font = QFont("Arial", 14) # 设置字体大小 painter.setFont(font) text = f"{self.soc:.1f}%" # 百分比格式化为一位小数 text_width = painter.fontMetrics().width(text) # 获取文字宽度 text_height = painter.fontMetrics().height() # 获取文字高度 painter.setPen(Qt.black) # 设置文字颜色为黑色 painter.drawText( (self.width() - text_width) // 2, # 水平居中 y + height + text_height + 5, # 放置在电池图标下方 text ) def get_soc_from_total_voltage(self, total_voltage): """ 调用外部逻辑计算电量百分比 """ from battery_logic import get_soc_from_total_voltage return get_soc_from_total_voltage(total_voltage) def get_battery_color(self, soc): """ 调用外部逻辑获取电池颜色 """ from battery_logic import get_battery_color return get_battery_color(soc) def update_voltage(self, total_voltage): # 更新电池电压并重新绘制 self.total_voltage = total_voltage self.soc = self.get_soc_from_total_voltage(self.total_voltage) self.update() # 触发重新绘制 class MainWindow(QWidget): def __init__(self): super().__init__() self.battery_voltage = 24.4 # 默认初始电压 self.init_ui() def init_ui(self): self.setWindowTitle("电池状态") # 设置窗口标题 self.setFixedSize(300, 120) # 设置固定窗口大小 # 创建电池组件 self.battery_widget = BatteryWidget(total_voltage=self.battery_voltage) layout = QVBoxLayout() layout.addWidget(self.battery_widget) self.setLayout(layout) def update_battery_voltage(self, total_voltage): """ 公共接口:更新电池电压 :param total_voltage: 新的总电压值 """ self.battery_widget.update_voltage(total_voltage)