-1

Need help to develop a progress bar in pyside like what we see in windows 10. while charging it has to show the progress bar along with the plug symbol.

enter image description here

After full charge the progress bar should be like below

enter image description here

Already I developed the code for horizontal progress bar. I need to emboss progress bar image attached above over the existing progress bar. Here is my code

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')

I am trying to send serial data from Arduino Uno so that progress bar has to progress according to the serial data. Its starts at 30% and ends at 100% and again rolls back to 30%. But When I compile the code I got the progress bar image with 30% progress value and after that it is not progressing. I am also getting some errors when i compile the code. Here is my full code

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_())

when i compile the code i got the following error

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

And This is my arduino uno code

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);
}
}

This is the output iam getting enter image description here

  • Simple error, use `self.pbar` in the constructor – alec Sep 22 '20 at 18:22
  • The progress bar value is incrementing in 10s (30,40,50...). Why is it so?. In my Arduino program i am incrementing the value by one (i+1) only. – vijayakumar sargunam Sep 23 '20 at 04:18
  • It seems it does not update each time a value is set. Reimplement `setValue` and call `self.repaint()` – alec Sep 23 '20 at 05:52
  • It worked finally thank you very much alec. I need to change the color of the Text (percentage value) when the progress bar reaches it. Initially the text should be in white color and when the progress bar reaches the text, the percentage value has to change to black color. And also i need to change the size of percentage value. The plug can be colored full with black color. – vijayakumar sargunam Sep 25 '20 at 09:09

1 Answers1

1

You could subclass QProgressBar and draw it with 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)

Call setCharging(True) to draw the plug.

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_())

enter image description here

alec
  • 5,799
  • 1
  • 7
  • 20
  • Hi alec thanks for your help. Is it possible to change the orientation of the progress bar. How to change it if i need vertical progress bar. And also i need to show the value (percentage of charging). – vijayakumar sargunam Sep 22 '20 at 04:15
  • @vijayakumarsargunam I've edited the answer to include both orientations and value. If it answers your questions please approve the answer. – alec Sep 22 '20 at 05:58
  • I got what i want. Thank you very much for the help. Iam also trying to make the progress bar to progress along with the serial data. Iam having some difficulties in that. Above I attached my full code. – vijayakumar sargunam Sep 22 '20 at 11:21