You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySide开发Windows 10风格电池充电进度条及串口故障排查

Fixing AttributeError & Implementing Windows 10-Style Battery Progress Bar with Serial Control

Let's break down your issues step by step: first resolving the AttributeError blocking your progress, then getting the serial-controlled updates working, and finally polishing the custom battery UI.

1. Fixing the AttributeError: 'Template' object has no attribute 'pbar'

This error pops up because your Template class doesn't properly initialize pbar as an instance attribute, or you're trying to access it incorrectly. Here's the corrected core of your PySide code:

Corrected PySide Class Snippet

from PySide6.QtWidgets import QWidget, QProgressBar, QVBoxLayout
from PySide6.QtCore import QThread, Signal

class Template(QWidget):
    def __init__(self):
        super().__init__()
        # Initialize progress bar as an instance attribute (critical fix!)
        self.pbar = QProgressBar(self)
        self.pbar.setRange(0, 100)
        self.pbar.setValue(30)  # Starting value
        
        layout = QVBoxLayout()
        layout.addWidget(self.pbar)
        self.setLayout(layout)
        
        # Set up background serial thread to avoid UI freezes
        self.serial_thread = SerialThread()
        self.serial_thread.progress_updated.connect(self.update_progress)
        self.serial_thread.start()
    
    def update_progress(self, value):
        # Safely update UI from main thread (required for PySide)
        self.pbar.setValue(value)
        # Toggle battery style based on charge state
        if value >= 100:
            self.set_full_battery_style()
        else:
            self.set_charging_style()
    
    def set_charging_style(self):
        # Custom stylesheet with charging plug icon and fill progress
        self.pbar.setStyleSheet("""
            QProgressBar {
                border: 2px solid #888;
                border-radius: 6px;
                background-image: url("battery_empty.png");
                background-size: contain;
                background-repeat: no-repeat;
                background-position: center;
            }
            QProgressBar::chunk {
                background-image: url("battery_fill.png");
                background-size: contain;
                background-repeat: repeat-x;
                border-radius: 4px;
            }
        """)
    
    def set_full_battery_style(self):
        # Stylesheet for fully charged state
        self.pbar.setStyleSheet("""
            QProgressBar {
                border: 2px solid #2ecc71;
                border-radius: 6px;
                background-image: url("battery_full.png");
                background-size: contain;
                background-repeat: no-repeat;
                background-position: center;
            }
        """)

# Background thread to handle serial communication without blocking UI
class SerialThread(QThread):
    progress_updated = Signal(int)
    
    def run(self):
        import serial
        # Adjust COM port and baud rate to match your Arduino setup
        ser = serial.Serial('COM3', 9600, timeout=1)
        while True:
            if ser.in_waiting > 0:
                try:
                    # Clean and parse serial data
                    raw_data = ser.readline().decode('utf-8').strip()
                    progress = int(raw_data)
                    # Ensure value stays within valid range
                    if 0 <= progress <= 100:
                        self.progress_updated.emit(progress)
                except ValueError:
                    # Skip invalid non-integer data
                    pass
        ser.close()

Key fixes here:

  • self.pbar is now properly initialized as an instance attribute in __init__, so your code can access it without errors.
  • Serial communication is moved to a separate QThread to prevent UI freezes, and we use a Signal to send progress updates to the main thread (PySide requires all UI updates to happen on the main thread).

2. Fixing Progress Stuck at 30%

The stuck progress is almost certainly due to either messy serial data or UI thread blocking. Let's fix the Arduino code to send clean, parseable values:

Corrected Arduino Code

void setup() {
  Serial.begin(9600);
}

void loop() {
  // Simulate charge cycle: 30% → 100% → 30%
  static int progress = 30;
  static bool is_charging = true;
  
  Serial.println(progress);  // Send value as a newline-terminated string
  delay(500);  // Adjust delay to control update speed
  
  if (is_charging) {
    progress++;
    if (progress >= 100) is_charging = false;
  } else {
    progress--;
    if (progress <= 30) is_charging = true;
  }
}

Additional checks:

  • Verify your Arduino's serial port matches the one in the Python code (use Device Manager on Windows to find the correct COM port).
  • Open the Arduino Serial Monitor to confirm it's sending clean integers (one per line) from 30 to 100 and back.

3. Polishing the Windows 10-Style Battery UI

To match Windows 10's battery behavior:

  • Use custom PNGs for empty battery, charging fill, and full battery (ensure file paths in the stylesheet are correct—use absolute paths for testing if needed).
  • The ::chunk selector in the stylesheet controls the fill progress overlay, while the main QProgressBar style handles the base battery icon.
  • When hitting 100%, we switch to a full battery style with no fill chunk, just like Windows does.

内容的提问来源于stack exchange,提问作者vijayakumar sargunam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:27:50