Using two QProgressBar in MainWindow
-
Hi,
How are you implementing the file copy ?
-
Basically a loop over QFile::copy. It is clear that the bytes are not countable, but that I am not trying. It is simply counting the files copied.
There is one loop of jobs (each job has a different target location) and in the jobs a number of files. One progress bar shows the progress with respect to jobs and the other shows the progress of files in each job and goes for each job from 0 to max value.
-
@JonB
The class definition#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QProgressDialog> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT QProgressDialog *Progress; public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public slots: void splitCopyJobs (); void on_pbSource_pressed(); void on_pbTarget_pressed(); void sltJobs ( int cnt, int maxCnt ); void sltFiles ( int cnt, int maxCnt ); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
The implementation file
#include "MainWindow.h" #include "ui_MainWindow.h" #include <QDebug> #include <QFileDialog> #include <QTimer> #include "SplitCopyJobs.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); Progress = 0; ui->pbJobs->setVisible( false ); ui->pbFiles->setVisible( false ); } MainWindow::~MainWindow() { delete ui; } void MainWindow::splitCopyJobs() { if ( QDir ( ui->pbSource->text() ).exists() && QDir( ui->pbTarget->text() ).exists() ) { SplitCopyJobs jobs; connect( &jobs, &SplitCopyJobs::sigJobs, this, &MainWindow::sltJobs ); connect( &jobs, &SplitCopyJobs::sigCopying, this, & MainWindow::sltFiles ); jobs.runSplitCopy ( ui->pbSource->text(), ui->pbTarget->text() ); ui->pbSource->setText( "-- Select --" ); ui->pbTarget->setText( "-- Select --" ); } } void MainWindow::sltJobs ( int cnt, int maxCnt ) { // if ( !Progress ) // { // Progress = new QProgressDialog ( "Number of jobs ", QString (), 0, maxCnt ); // Progress->setWindowModality( Qt::WindowModal ); // } // Progress->setValue ( cnt ); if ( ! cnt ) { ui->pbJobs->setMinimum ( 0 ); ui->pbJobs->setMaximum ( maxCnt ); ui->pbJobs->setVisible ( true ); ui->pbJobs->setWindowModality( Qt::WindowModal ); } ui->pbJobs->setValue ( cnt ); } void MainWindow::sltFiles ( int cnt, int maxCnt ) { if ( ! cnt ) { ui->pbFiles->setMinimum ( 0 ); ui->pbFiles->setMaximum ( maxCnt ); ui->pbFiles->setVisible ( true ); ui->pbFiles->setWindowModality( Qt::WindowModal ); } ui->pbFiles->setValue ( cnt ); }
Screenshot of ui
Basically all is done in splitCopyJobs and i is also blocking the event loop the whole time until all files are copied.
However, when this is the problem, why would then the progress bars change at all?
As the code had some separate progress dialog is shown above. The progress dialog and at the same time progress bars were showing all as expected. After commenting out the progress dialog all seem to work, but only until the upper bar reached 25%. In the background the files were still copied, but both bars remained frozen.
-
Might be a silly question but are you sure that the counter and maximum values are accurate ?
-
Yes, that is one of the routines sending the signals.
The principle outline of the other is similar.void SplitCopyJobs::copy ( const QFileInfoList & lstintrvl, const QString & oldBase, const QString & newJob ) { int maxCnt = lstintrvl.size(); sigCopying ( 0, maxCnt ); int cnt = 0; for ( QFileInfoList::const_iterator it = lstintrvl.begin(); it != lstintrvl.end(); ++it ) { QString oldName = it->absoluteFilePath(); QString newName = newJob + oldName.mid ( oldBase.size() ); QString targetPath = QFileInfo ( newName ).absolutePath(); QDir tdir ( targetPath ); if ( !tdir.exists() ) { tdir.mkpath( targetPath ); } QFile::copy( oldName, newName ); sigCopying ( ++cnt, maxCnt ); } }
-
@koahnig
I think, just as @kshegunov says, that although you are deliveringsigCopying
you are not giving any call for the event loop to be processed, to act on the signal to update the progress bar? You are supposed to call something likeQApplication.processEvents()
regularly during a "long-running operation" to allow events to be processed and your bar to get updated? -
Thanks for confirming my suspision I expressed already in my initial post
@koahnig said in Using two QProgressBar in MainWindow:
Basically the whole copying is done in one slot of the main window. Would I need to shift that into a separate thread?
Is not really logical because that worked and suddenly stopped.However, it is really confusing when something works and suddenly not completely correct. I was not sure if there is some "special magic" somewhere.
-
@koahnig said in Using two QProgressBar in MainWindow:
However, it is really confusing when something works and suddenly not completely correct.
Indeed, although the confusing part is that it doesn't really work, only gives the appearance of working, I get that a lot with my code. ;)