PyQt Progressbar QThread not working when rendering a graph
Asked Answered
A

0

0

I looked at this answer here which was very helpful, but it's not working as expected when trying to render a plot.

The plot is working but the progress bar is not progressing, it will just jump to 100% after the plot is rendered. Of course, I would like the progress bar to be progressing while the plot is rendering, not after it's finished.

I think, I might be missing a PyQt function to somehow connect the event or the pyqt signal, but actually I have no idea how to fix this.

Here is, what I hope to be, a Minimal, Complete, and Verifiable example:

import sys
from pandas.tools.plotting import scatter_matrix
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import time

from PyQt5.QtWidgets import (QWidget, QProgressBar, 
    QPushButton, QApplication, QVBoxLayout)
from PyQt5 import QtCore, QtGui

class MyCustomWidget(QWidget):

    def __init__(self, parent=None):
        super(MyCustomWidget, self).__init__(parent)
        layout = QVBoxLayout(self)

        self.progressBar = QProgressBar(self)
        self.progressBar.setRange(0,1)
        layout.addWidget(self.progressBar)
        self.count = 0
        button = QPushButton("Start", self)
        layout.addWidget(button)
        self.df = pd.DataFrame(np.random.rand(3, 12))

        button.clicked.connect(self.onStart)

        self.myLongTask = TaskThread()
        self.myLongTask.taskFinished.connect(self.onFinished)

        self.show()

    def onStart(self):
        scatter_matrix(self.df, alpha=0.8, figsize=(7, 7), diagonal='kde')
        self.scatter = plt
        self.scatter.suptitle('Data Scatter Matrix Plot', size=16)
        self.progressBar.setRange(0,0)
        self.progressBar.setValue(1)
        self.myLongTask.start()
        self.scatter.show()

    def onFinished(self):
        self.progressBar.setRange(0,1)


class TaskThread(QtCore.QThread):
    taskFinished = QtCore.pyqtSignal()
    def run(self):
        time.sleep(3)
        self.taskFinished.emit()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = MyCustomWidget()
    sys.exit(app.exec_())
Alcheringa answered 13/11, 2017 at 3:17 Comment(18)
What is the problem?Breaker
@Breaker Thanks, I edited the question explaining the problem.Alcheringa
What I'm seeing is that it's only going to vary by one unit.Breaker
And this is changing correctly since you just change it to 1 in onFinishedBreaker
@Breaker I tried to change that value but it still won't work for some reason.Alcheringa
I do not understand what you expect, you could explain in detail.Breaker
How do you want the QProgressBar to vary?Breaker
@Breaker Oh, I forgot to save my edit earlier, now I provided a little bit more details of what the problem is.Alcheringa
You must indicate the progress to QProgressBar, QProgressBar does not know how it is varying the plotting process. For example, if I am reading files from a folder then the percentage is the number of files read with respect to the total number of files, and the one that calculates it is our code, and that value is passed, QProgressBar does not guess the percentage.Breaker
@Breaker Yes, clearly that's the problem. Can that problem be solved in this type of plotting situations?Alcheringa
In the example you link shows how to use QProgressBar as a busy indicator, that is, the chunk is moving from left to right, and from right to left constantly until you indicate that it ends. Is that what you want?Breaker
Showing the percentage is impossible if the function does not indicate the percentage of work.Breaker
@Breaker No, the busy indicator is not what I want, I would like the progress bar to move from left to right only and a constant motion.Alcheringa
@Breaker So, is there a way to indicate the percentage in the function for a plot?Alcheringa
I do not know any method, and most likely it does not exist since the plot libraries are not interested in showing the percentage of progress.Breaker
That's kind of what I though after hours of trying to make this work. The issue is that these scatter matrix plots could take a while to render if the data sets a big. Thus, the user will think the app is crashed after 30 seconds of waiting and nothing is happening. Do you have any suggestions on how to find an other solution for this?Alcheringa
Use an indicator that the process is working as for example the elapsed time, or that it says progressing.Breaker
@Breaker Yes, that's what I will do. Thanks so much for your help with this problem. I really appreciate it! You're always very helpful. Thanks again.Alcheringa

© 2022 - 2024 — McMap. All rights reserved.