[Résolu] [Qt] [C++] QProgressBar ne s'update pas

Bonjour,

J’ai fait un petit GUI plus élégant que la ligne de commande pour calculer les nombres premiers, mais la QProgressBar ne s’actualise pas, sauf à la fin des calculs. J’ai testé plein de méthodes dont le qApp->processEvents(); mais je n’ai toujours pas résolu mon problème.

Voici le mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWidget>
#include <QGridLayout>
#include <QFormLayout>
#include <QSpinBox>
#include <QPushButton>
#include <QLabel>
#include <QProgressBar>
#include "cmath"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("Primus");
    setGeometry(240, 240, 200, 240);

    QWidget *mainWidget = new QWidget();
    setCentralWidget(mainWidget);

    QGridLayout *mainLayout = new QGridLayout();
    mainWidget->setLayout(mainLayout);

    QFormLayout *formLayout = new QFormLayout();
    mainLayout->addLayout(formLayout, 0, 0);

    minSpin = new QSpinBox();
    minSpin->setMinimum(2);
    minSpin->setMaximum(pow(10, 48));
    maxSpin = new QSpinBox();
    maxSpin->setMinimum(2);
    maxSpin->setMaximum(pow(10, 48));
    maxSpin->setValue(1000);

    formLayout->addRow("Min", minSpin);
    formLayout->addRow("Max", maxSpin);

    QPushButton *buttonCalculate = new QPushButton("Calculate");
    mainLayout->addWidget(buttonCalculate, 1, 0);
    connect(buttonCalculate, SIGNAL(clicked()), this, SLOT(calculate()));

    progressBar = new QProgressBar();
    progressBar->setValue(0);
    progressBar->setEnabled(false);
    mainLayout->addWidget(progressBar, 2, 0);

    resultsExaminated = new QLabel("Examinated: 0");
    mainLayout->addWidget(resultsExaminated, 3, 0);

    resultsFound = new QLabel("Found: 0");
    mainLayout->addWidget(resultsFound, 4, 0);

    resultsPercentage = new QLabel("Percentage: 0.00 %");
    mainLayout->addWidget(resultsPercentage, 5, 0);
}

void MainWindow::calculate()
{
    int min;
    int max;
    min = minSpin->value();
    max = maxSpin->value();

    int i;
    int n(0);
    for(i = min; i < max ; i++) {
        int j;
        bool prime(true);
        for(j = min; j < sqrt(i); j++) {
            if (i%j == 0) {
                prime = false;
            }
        }
        if(prime) {
            n++;
        }
        int progress = (int)round((i-min)/(max-min)*100);
        progressBar->setValue(progress);
        qApp->processEvents();
    }

    progressBar->setValue(100);
    resultsExaminated->setText("Examinated: " + QString::number(max-min));
    resultsFound->setText("Found: " + QString::number(n));
    resultsPercentage->setText("Percentage: " + QString::number((double)(ceil(n/(max-min)*1000)/1000)) + " %");
}

MainWindow::~MainWindow()
{
    delete ui;
}

Merci

Salut

Il me semble que c’est parce que tu es en simple thread et que le rafraîchissement de la barre progression ne se fera qu’à la fin de l’exécution de la méthode calculate(). Je crois qu’il faut forcer ce rafraîchissement avec progressBar->update() ou progressBar->repaint() après progressBar->setValue(progress) (en favorisant update par rapport à repaint)

Salut,

J’ai donc écrit cela :
int progress = (int)round((i-min)/(max-min)*100);
progressBar->setValue(progress);
progressBar->update();

Mais ça ne marche toujours pas, ça ne s’actualise qu’à la fin du calcul.

Oublie ce que j’ai dit avant.

Je viens de reproduire ton code. Il y a une subtilité vis-à-vis de round

Essaie ceci (la méthode update n’est plus nécessaire) :

int progress = ( int ) round ( ( double ) ( i - min ) / ( max - min ) * 100 );

Remarque le ( double ) devant ( i - min )

NB: Sorry pour les espacements dans les termes du code, c’est une manie que j’ai.

Merci ça marche ! Donc en fait, c’était juste un problème de calcul qui restait en int ?

En fait, round s’attend à du double. Mais ( i - min ) et ( max - min ) sont des int et le résultat de la division d’un int par un int donne un quotient int et le reste de la division est ignorée. Donc, dans ton cas, la division des deux entiers donne toujours un nombre décimal en dessous de 1. Par conséquent tu as un quotient de 0 et un reste supérieur à 0. Multiplié 0 par 100 donne toujours 0. Arrondir 0 donne 0.

En le mettant en double on garde les décimales lorsqu’on multiplie par 100.

1 « J'aime »

Par contre, maintenant, mon pourcentage affiche toujours -2%, je n’arrive pas à identifier le problème.

Pour rappel :

resultsPercentage->setText("Percentage: " + QString::number((double)((ceil(n/max-min)*1000)/1000)) + " %");

Même explication, un division d’un entier par un autre plus grand donnera toujours 0.

Essaye donc

resultsPercentage->setText( "Percentage: " + QString::number( ( ceil( ( double ) n / ( max - min ) * 1000) / 1000 ) ) + " %" );

J’avais testé en lisant votre message de le mettre pour n, max et min mais ça n’avait pas marché, mais visiblement ça marche avec votre code.

Merci pour tout !

Au plaisir