Mr RC
Mr RC

Reputation: 189

Python 3.5, pyqt5 progress bar gui in seperate window

I am new to PyQt5 and pretty new to Python. I am trying to create a graphical user interface using PyQt5 in Python 3.5, where I click a button to launch a separate window in which the progress bar iterates up to 100 and then closing the window at the end of iteration to generate a message "it worked".

The problem is the progress bar is created but doesn't update and after reaching the end it doesn't display the message that it worked. When I try to debug it crashes completely with no warning as to why. I don't know how else to debug the code

My progress bar code is shown below:

from PyQt5 import QtCore, QtWidgets
import sys

class Ui_Form(object):
def setupUi(self, Form):
    Form.setObjectName("Form")
    Form.resize(1075, 84)
    self.progressBar = QtWidgets.QProgressBar(Form)
    self.progressBar.setGeometry(QtCore.QRect(30, 30, 1000, 35))
    sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
    sizePolicy.setHorizontalStretch(0)
    sizePolicy.setVerticalStretch(0)
    sizePolicy.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth())
    self.progressBar.setSizePolicy(sizePolicy)
    self.progressBar.setMinimumSize(QtCore.QSize(1000, 35))
    self.progressBar.setMaximumSize(QtCore.QSize(1000, 35))
    self.progressBar.setProperty("value", 0)
    self.progressBar.setObjectName("progressBar")

    self.retranslateUi(Form)
    QtCore.QMetaObject.connectSlotsByName(Form)

def setValue(self, val):
    self.progressBar.setProperty("value", val)

def retranslateUi(self, Form):
    _translate = QtCore.QCoreApplication.translate
    Form.setWindowTitle(_translate("Form", "Progress bar"))

The main program is given below

from PyQt5.QtWidgets import QApplication, QDialog, QWidget, QPushButton, QMessageBox
import ProgressBar
import sys

class App(QWidget):
def __init__(self):
    super().__init__()
    self.title = 'PyQt5 button - pythonspot.com'
    self.left = 200
    self.top = 200
    self.width = 320
    self.height = 200
    self.initUI()

def initUI(self):
    self.setWindowTitle(self.title)
    self.setGeometry(self.left, self.top, self.width, self.height)

    button = QPushButton('PyQt5 button', self)
    button.setToolTip('This is an example button')
    button.move(100, 70)
    button.clicked.connect(self.on_click)

    self.show()

def on_click(self):
    print('PyQt5 button click')

    app1 = QApplication(sys.argv)
    window = QDialog()
    ui = ProgressBar.Ui_Form()
    ui.setupUi(window)
    window.show()

    for i in range(0, 100):
        ui.setValue(((i + 1) / 100) * 100)

    app1.quit()

    QMessageBox.information(self, "Message", "Data Loaded")

if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())

Any help would be greatly appreciated.

Upvotes: 0

Views: 7101

Answers (2)

Mr RC
Mr RC

Reputation: 189

Figured out solution eventually. 3 problems:

1) Should only call QApplication once in the main application an not again

2) Add QApplication.processEvents() to the forloop so it updates the progressbar continuously

3) Add window.close() after the forloop so it closes

Upvotes: -2

Mr RC
Mr RC

Reputation: 189

Here is my final code. I have tried to include some good practices with using pyqt designer and not editing the created file directly but run it from another file and call into it. This has made things much easier when I wanted to change things as suggested. I have also included a time.sleep(0.1) to the code to slow it down so you can see it working. Hope it helps.

ProgressBar_ui.py - file generated by converted in python from ProgressBar.ui

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Base.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
    def setupUi(self, Form):
    Form.setObjectName("Form")
    Form.resize(1075, 84)
    self.progressBar = QtWidgets.QProgressBar(Form)
    self.progressBar.setGeometry(QtCore.QRect(30, 30, 1000, 35))
    sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
    sizePolicy.setHorizontalStretch(0)
    sizePolicy.setVerticalStretch(0)
    sizePolicy.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth())
    self.progressBar.setSizePolicy(sizePolicy)
    self.progressBar.setMinimumSize(QtCore.QSize(1000, 35))
    self.progressBar.setMaximumSize(QtCore.QSize(1000, 35))
    self.progressBar.setProperty("value", 0)
    self.progressBar.setObjectName("progressBar")

    self.retranslateUi(Form)
    QtCore.QMetaObject.connectSlotsByName(Form)

def retranslateUi(self, Form):
    _translate = QtCore.QCoreApplication.translate
    Form.setWindowTitle(_translate("Form", "Progress bar"))

ProgressBar.py - Calls ProgrssBar.ui

from PyQt5 import QtCore, QtGui, QtWidgets
import sys

from ProgressBar_ui import Ui_Form

class ProgressBar(QtWidgets.QDialog, Ui_Form):
    def __init__(self, desc = None, parent=None):
        super(ProgressBar, self).__init__(parent)
        self.setupUi(self)
        self.show()

        if desc != None:
            self.setDescription(desc)

    def setValue(self, val): # Sets value
        self.progressBar.setProperty("value", val)

    def setDescription(self, desc): # Sets Pbar window title
        self.setWindowTitle(desc)

def main():
    app = QtWidgets.QApplication(sys.argv)      # A new instance of QApplication
    form = ProgressBar('pbar')                        # We set the form to be our MainWindow (design)
    app.exec_()                                 # and execute the app

if __name__ == '__main__':                      # if we're running file directly and not importing it
    main()                                      # run the main function

Main_program.py - Run from here

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox
from ProgressBar import ProgressBar
import sys, time

class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 button - pythonspot.com'
        self.left = 200
        self.top = 200
        self.width = 320
        self.height = 200
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        button = QPushButton('PyQt5 button', self)
        button.setToolTip('This is an example button')
        button.move(100, 70)
        button.clicked.connect(self.on_click)

        self.show()

    def on_click(self):
        pb = ProgressBar()

        for i in range(0, 100):
            time.sleep(0.05)
            pb.setValue(((i + 1) / 100) * 100)
            QApplication.processEvents()

        pb.close()

        QMessageBox.information(self, "Message", "Data Loaded")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Upvotes: 4

Related Questions