I’m trying to show a busy waiting bar when one function is executing, my problem is it stop moving once the function starts.
MyProgressDialog *progBar= new MyProgressDialog();
QProgressBar* bar = new QProgressBar(progBar);
bar->setRange(0, 0);
bar->setValue(0);
progBar->setBar(bar);
QString labeltext=QString("<qt> <center><big><b>%1</b></big></center> <br><b>%2</b><br> %3 <br><b>%4</b><br> %5</qt>")
.arg(progBar->labeltext)
.arg("File in :")
.arg(FileI)
.arg("File out :")
.arg(FileO);
progBar->label->setText(labeltext);
progBar->setValue(10);
progBar->show();
progBar->setValue(20);
Sleep(500);
progBar->setValue(50);
Sleep(500);
MyFunction(FileI,FileO,mode,key);
Sleep(500);
progBar->setValue(80);
Sleep(500);
progBar->setValue(100);
progBar->close();
delete bar;
delete progBar;
I warpped my function with a sleep and set value in purpose to let it moving but in vain, when I remove them MyProgressdialog didn’t show its contents, am I need to lunch my function in a separate thread ?
I tried to use QFutureWatcher:
QFutureWatcher<void> futureWatcher;
QFuture<void> f1 = run(
MyFunction,
filePath,
file.absolutePath()+"/OUT_"+fileN,
1,
key
);
QObject::connect(&futureWatcher, SIGNAL(finished()), progBar, SLOT(reset()));
QObject::connect(progBar, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), progBar, SLOT(setRange(int,int)));
QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), progBar, SLOT(setValue(int)));
// Start the computation.
futureWatcher.setFuture(f1);
// Display the dialog and start the event loop.
progBar->exec();
futureWatcher.waitForFinished();
delete progBar;
It works fine and my bar is moving when I call MyFunction just one time (for one file) but the problem occurs when I call MyFunction more than one time (for many files successively): it works but I get the same OUT_file for all files treated, I think it is multithreading issue.
EDIT: class MyProgressDialog
class MyProgressDialog: public QProgressDialog
{
Q_OBJECT
public:
MyProgressDialog()
{
qDebug()<<"MyProgressDialog constructor";
label=new QLabel(this);
QPalette* palette = new QPalette();
palette->setColor(QPalette::Window,"#F8F8FF");
setPalette(*palette);
QFont* font = new QFont("Courier New");
font->setItalic(true);
font->setPixelSize(15);
setFont(*font);
adjustSize();
setWindowIcon(QIcon(QApplication::applicationDirPath()+"/icons/icon1.png"));
setWindowFlags(Qt::WindowStaysOnTopHint);
setMinimumWidth(500);
setMinimumHeight(200);
labeltext=QString("Please wait until Encryption/Decryption was done");
label->setText(labeltext);
label->adjustSize();
label->setWordWrap (true);
setLabel(label);
setRange(0,100);
setWindowTitle("MyFunction progress");
setModal(true);
}
~MyProgressDialog()
{
qDebug()<<"MyProgressDialog destructor";
delete label;
}
public:
int value;
QString labeltext;
QLabel* label;
};
UI in Qt is event driven. So executing your code in same thread as ui will block every ui event untill your function is finished. There are two aproaches to show progress.
setValueandshowcalls callQApplication::processEvents();static method. CallingQApplication::processEvents()will dispatch events currently queued on event loop. Those events include all ui related eventsHere is code sample for gcc/mingw gcc
It shows progress bar and steps it by 10 every 0,25s
Your code should look something like this: