首页 > 解决方案 > 使用pyside设计windows 10电池充电进度条

问题描述

需要帮助在 pyside 中开发进度条,就像我们在 Windows 10 中看到的那样。充电时,它必须显示进度条以及插头符号。

在此处输入图像描述

充满电后,进度条应如下所示

在此处输入图像描述

我已经开发了水平进度条的代码。我需要将上面附加的进度条图像压印在现有进度条上。这是我的代码

def initUI(self): 
        self.pbar = QtGui.QProgressBar(self)
        self.pbar.setGeometry(30, 40, 300, 25)
        self.pbar.setAlignment(QtCore.Qt.AlignCenter) 
        self.pbar.setMinimum(0)
        self.pbar.setValue(y)
        self.pbar.setValue(40)

        self.pbar.setRange(0,100)
        self.pbar.setStyleSheet("QProgressBar::chunk"
                         "{"
                         "background-color: Green;"
                         "margin: 4px;"
                         "}")
           
        self.setGeometry(300, 300, 480, 170)
        self.setWindowTitle('ProgressBar')

我正在尝试从 Arduino Uno 发送串行数据,以便进度条必须根据串行数据进行。它从 30% 开始,以 100% 结束,然后再次回滚到 30%。但是当我编译代码时,我得到了具有 30% 进度值的进度条图像,之后它就没有进度了。我在编译代码时也遇到了一些错误。这是我的完整代码

import serial
import time
import sys
from PySide.QtGui import *
from PySide import QtGui, QtCore
from PySide.QtCore import Signal

from time import sleep
list=['COM1','COM2','COM3','COM4','COM5','COM6','COM7','COM8','COM9','COM10','COM11','COM12','COM13','COM14','COM15','COM16','COM17','COM18',]
COM1='COM1'
COM2='COM2'
COM3='COM3'
COM4='COM4'
COM5='COM5'
COM6='COM6'
COM7='COM7'
COM8='COM8'
COM9='COM9'
COM10='COM10'
COM11='COM11'
COM12='COM12'
COM13='COM13'
COM14='COM14'
COM15='COM15'
COM16='COM16'
COM17='COM17'
COM18='COM18'
COM19='COM19'
time.sleep(1)
ser = serial.Serial()
i=1
while True:
    time.sleep(.2)
    print(i)
    ser.port = list[i]
    try:

        ser.open()
        if ser.isOpen()==True:
            print('connected')
            #print('arduino is on COMPORT'.join(i))
            break
        break

    except:
        print('waiting')
        i=i+1
        if i==18:
            print('Kindly remove usb cable and try again')
            break

ser.baudrate = 9600
x = ser.readline()
y = int(x)

class Battery(QProgressBar):

    def __init__(self, *args, **kwargs):
        super(Battery,self).__init__(*args, **kwargs)
        self.setTextVisible(False)
        self.charging = False
        self.setStyleSheet('''
        QProgressBar {
            border: 4px solid white;
            background-color: #0070db;
            margin-top: 12px;
        }
        QProgressBar:horizontal {
            height: 60px;
            width: 120px;
            margin-right: 12px;
        }
        QProgressBar:vertical {
            height: 120px;
            width: 60px;
            margin-left: 12px;
        }
        QProgressBar::chunk {
            background-color: white;
            margin: 4px;
        }''')

    def setCharging(self, state):
        self.charging = state
        self.repaint()

    def paintEvent(self, event):
        super(Battery,self).paintEvent(event)
        qp = QPainter(self)
        qp.setPen(QtCore.Qt.NoPen); qp.setBrush(QtCore.Qt.white)
        w, h = self.width(), self.height()
        if self.orientation() == QtCore.Qt.Horizontal:
            qp.drawRect(w, 12 + h / 4, -12, h / 2 - 12)
            dx, dy = 0, 12
        else:
            qp.drawRect(12 + w / 4, 0, w / 2 - 12, 12)
            dx, dy = 12, 0

        qp.setPen(self.palette().text().color())
        qp.drawText(self.rect().adjusted(dx, dy, 0, 0), QtCore.Qt.AlignCenter, self.text())
        qp.setPen(QtCore.Qt.NoPen)
        
        if self.charging:
            qp.setBrush(self.parent().palette().window())
            path = QPainterPath()
            if self.orientation() == QtCore.Qt.Horizontal:
                qp.drawRect(0, 0, 12, h)
                path.moveTo(12, h)
                path.lineTo(12, 12 + h / 3)
                path.quadTo(22, 12 + h / 3, 22, 24)
                path.lineTo(22, 14)
                path.lineTo(2, 14)
                path.lineTo(2, 24)
                path.quadTo(2, 12 + h / 3, 12, 12 + h / 3)
                path.moveTo(7, 12); path.lineTo(7, 0)
                path.moveTo(17, 12); path.lineTo(17, 0)
            else:
                qp.drawRect(0, h, w, -12)
                path.moveTo(w, h - 12)
                path.lineTo(12 + w / 3, h - 12)
                path.quadTo(12 + w / 3, h - 22, 24, h - 22)
                path.lineTo(14, h - 22)
                path.lineTo(14, h - 2)
                path.lineTo(24, h - 2)
                path.quadTo(12 + w / 3, h - 2, 12 + w / 3, h - 12)
                path.moveTo(12, h - 7); path.lineTo(0, h - 7)
                path.moveTo(12, h - 17); path.lineTo(0, h - 17)
            
            pen = QPen(qp.brush(), 12, QtCore.Qt.SolidLine, QtCore.Qt.SquareCap, QtCore.Qt.MiterJoin)
            qp.strokePath(path, pen)
            pen.setWidth(4); pen.setColor(QtCore.Qt.white); qp.setPen(pen)
            qp.setBrush(self.palette().window())
            qp.drawPath(path)

class Template(QWidget):

    def __init__(self):
        super(Template, self).__init__()
        grid = QGridLayout(self)
        grid.setSpacing(50)
        pbar = Battery(value=y)
        pbar.setCharging(True)
        grid.addWidget(Battery(value=y), 0, 0)
        grid.addWidget(pbar, 0, 1)
        
        pbar = Battery(value=y, orientation=QtCore.Qt.Vertical)
        pbar.setCharging(True)
        grid.addWidget(Battery(value=y, orientation=QtCore.Qt.Vertical), 1, 0, QtCore.Qt.AlignCenter)
        grid.addWidget(pbar, 1, 1, QtCore.Qt.AlignCenter)
        self.setStyleSheet('''
        Template {
            background-color: #0070db;
        }''')
        self.myLongTask = TaskThread()
        # connect signal before thresd is started
        self.myLongTask.notifyProgress.connect(self.on_progress)
        # start thread
        self.on_start()
        

    
    def on_start(self):
        self.myLongTask.start()

    def on_progress(self, y):
        self.pbar.setValue(y)


class TaskThread(QtCore.QThread):
   #notifyProgress = QtCore.pyqtSignal(int)
   notifyProgress = Signal(int)

   def run(self):
        while True:
            x = ser.readline()
            y = int(x)
            #for y in range(100):
            self.notifyProgress.emit(y)
       #    sleep(0.1)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Template()
    window.show()
    sys.exit(app.exec_())

当我编译代码时出现以下错误

File "C:\Python27\winbat.py", line 166, in on_progress
    self.pbar.setValue(y)
AttributeError: 'Template' object has no attribute 'pbar'

这是我的arduino uno代码

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  //Serial.println("hello");
  for (int i = 30; i <= 100; i++) {
  Serial.println(i);
  delay(1000);
}
}

这是我在 此处输入图像描述的输出

标签: pythonpysideqprogressbar

解决方案


您可以继承 QProgressBar 并使用 QPainter 绘制它。

class Battery(QProgressBar):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setTextVisible(False)
        self.charging = False
        self.setStyleSheet('''
        QProgressBar {
            border: 4px solid white;
            background-color: #0070db;
            margin-top: 12px;
        }
        QProgressBar:horizontal {
            height: 60px;
            width: 120px;
            margin-right: 12px;
        }
        QProgressBar:vertical {
            height: 120px;
            width: 60px;
            margin-left: 12px;
        }
        QProgressBar::chunk {
            background-color: white;
            margin: 4px;
        }''')

    def setCharging(self, state):
        self.charging = state
        self.repaint()

    def paintEvent(self, event):
        super().paintEvent(event)
        qp = QPainter(self)
        qp.setPen(Qt.NoPen); qp.setBrush(Qt.white)
        w, h = self.width(), self.height()
        if self.orientation() == Qt.Horizontal:
            qp.drawRect(w, 12 + h / 4, -12, h / 2 - 12)
            dx, dy = 0, 12
        else:
            qp.drawRect(12 + w / 4, 0, w / 2 - 12, 12)
            dx, dy = 12, 0

        qp.setPen(self.palette().text().color())
        qp.drawText(self.rect().adjusted(dx, dy, 0, 0), Qt.AlignCenter, self.text())
        qp.setPen(Qt.NoPen)
        
        if self.charging:
            qp.setBrush(self.parent().palette().window())
            path = QPainterPath()
            if self.orientation() == Qt.Horizontal:
                qp.drawRect(0, 0, 12, h)
                path.moveTo(12, h)
                path.lineTo(12, 12 + h / 3)
                path.quadTo(22, 12 + h / 3, 22, 24)
                path.lineTo(22, 14)
                path.lineTo(2, 14)
                path.lineTo(2, 24)
                path.quadTo(2, 12 + h / 3, 12, 12 + h / 3)
                path.moveTo(7, 12); path.lineTo(7, 0)
                path.moveTo(17, 12); path.lineTo(17, 0)
            else:
                qp.drawRect(0, h, w, -12)
                path.moveTo(w, h - 12)
                path.lineTo(12 + w / 3, h - 12)
                path.quadTo(12 + w / 3, h - 22, 24, h - 22)
                path.lineTo(14, h - 22)
                path.lineTo(14, h - 2)
                path.lineTo(24, h - 2)
                path.quadTo(12 + w / 3, h - 2, 12 + w / 3, h - 12)
                path.moveTo(12, h - 7); path.lineTo(0, h - 7)
                path.moveTo(12, h - 17); path.lineTo(0, h - 17)
            
            pen = QPen(qp.brush(), 12, Qt.SolidLine, Qt.SquareCap, Qt.MiterJoin)
            qp.strokePath(path, pen)
            pen.setWidth(4); pen.setColor(Qt.white); qp.setPen(pen)
            qp.setBrush(self.palette().window())
            qp.drawPath(path)

调用setCharging(True)绘制插头。

class Template(QWidget):

    def __init__(self):
        super().__init__()
        grid = QGridLayout(self)
        grid.setSpacing(50)
        pbar = Battery(value=100)
        pbar.setCharging(True)
        grid.addWidget(Battery(value=100), 0, 0)
        grid.addWidget(pbar, 0, 1)
        
        pbar = Battery(value=100, orientation=Qt.Vertical)
        pbar.setCharging(True)
        grid.addWidget(Battery(value=100, orientation=Qt.Vertical), 1, 0, Qt.AlignCenter)
        grid.addWidget(pbar, 1, 1, Qt.AlignCenter)
        self.setStyleSheet('''
        Template {
            background-color: #0070db;
        }''')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Template()
    window.show()
    sys.exit(app.exec_())

在此处输入图像描述


推荐阅读