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.pbaris now properly initialized as an instance attribute in__init__, so your code can access it without errors.- Serial communication is moved to a separate
QThreadto 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
::chunkselector in the stylesheet controls the fill progress overlay, while the mainQProgressBarstyle 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
相关产品推荐
相关产品推荐

