QProgressBar
-
hi i want to make a Progressbar, when i press the button it starts and when the task ends it arrives at 100% i tested this code but it does not work :
void tu::on_Lidar_clicked()
{QProgressBar pBAR ; QFutureWatcher<void>Watcher1; Watcher1.setFuture(QtConcurrent::run(T1)); QFutureWatcher<void>Watcher; Watcher.setFuture(QtConcurrent::run(T2)); connect (&pBAR, SIGNAL(canceled()), &Watcher, SLOT(cancel())); connect (&Watcher, SIGNAL(finished()),&pBAR , SLOT(reset())); connect (&Watcher, SIGNAL(progressRangeChanged(int,int)),&pBAR , SLOT(setRange(int,int))); connect (&Watcher, SIGNAL(progressValueChanged(int,int)),&pBAR , SLOT(setValue(int)));
}
Any help please -
@jagl said in QProgressBar:
QProgressBar pBAR ;
Your progress bar is a local variable which is destroyed as soon as on_Lidar_clicked() finishes. Also your watcher are local variables.
Make all these variables class members. -
@jsulm thanks for your replay
i did :
in the file .h:
public:
QProgressBar pBAR ;
QFutureWatcher<void> Watcher1;
QFutureWatcher<void>Watcher;
in the file .cpp:Watcher1.setFuture(QtConcurrent::run(T1)); Watcher.setFuture(QtConcurrent::run(T2)); connect (&pBAR, SIGNAL(canceled()), &Watcher, SLOT(cancel())); connect (&Watcher, SIGNAL(finished()),&pBAR , SLOT(reset())); connect (&Watcher, SIGNAL(progressRangeChanged(int,int)),&pBAR , SLOT(setRange(int,int))); connect (&Watcher, SIGNAL(progressValueChanged(int,int)),&pBAR , SLOT(setValue(int)));
}
But it didn't work -
@jagl I don't think you can use progressValueChanged() signal with https://doc.qt.io/qt-5/qtconcurrent.html#run (see the description there). How would it know how far your calculations are? You will need to go for a worker object which is executed in a thread and emits a signal to pass current progress to the outside world. See https://doc.qt.io/qt-5/qthread.html
-
@jsulm ok I will see thanks however I have another question please I would like when I click on the lidar button, the camera_capture button will be clicked will do that but it didn't work :
connect (ui->Lidar, SIGNAL(clicked()), ui->Capture_Camera, SLOT(clicked()));
any idea please -
-
@jsulm
thank you it works.
for the problem of QProgressBar I changed the programming but the progressbar is at 100% before the termination of Watcher1 and Watcher
code
.h:
public:
QTimer *m_timer;
QFutureWatcher<void>Watcher1;
QFutureWatcher<void>Watcher;
private slots:
void slotProcessBar();.cpp:
m_timer = new QTimer(this);
ui->progressBar->setRange(0, 99);
ui->progressBar->setValue(0);connect (ui->progressBar, SIGNAL(canceled()), &Watcher, SLOT(cancel())); connect (&Watcher, SIGNAL(finished()),ui->progressBar, SLOT(reset())); connect(m_timer, SIGNAL(timeout()), this, SLOT(slotProcessBar()));
void tu::slotProcessBar()
{
static int pos = 0;
if (pos == 100)
{
m_timer->stop();
return;
}ui->progressBar->setValue(pos++);
}
void tu::on_Lidar_clicked()
{m_timer->start(); Watcher1.setFuture(QtConcurrent::run(tu1)); Watcher.setFuture(QtConcurrent::run(tu2));
}
can you help me please -
@jagl You're not setting timer interval as far as I can see (https://doc.qt.io/qt-5/qtimer.html#interval-prop)
-
@jagl It is clear when the timer will start.
What I'm talking about is the timer interval.
If you read the link I posted you will see: "A QTimer with a timeout interval of 0 will time out as soon as all the events in the window system's event queue have been processed.". So, you will get the timeouts very fast and your progress bar will also reach very fast 100%.
But, I don't understand why you invented a timer here? It will only work if you know in advance how long your back ground task will run. But you don't, right? -
@jsulm Please now the ProgressBar works but it does not reset
connect (&Watcher1, SIGNAL(progressRangeChanged(int,int)),ui->progressBar, SLOT(setRange(int,int)));
connect (&Watcher1, SIGNAL(progressValueChanged(int,int)),ui->progressBar, SLOT(setValue(int)));
connect (&Watcher, SIGNAL(finished()),ui->progressBar , SLOT(reset())); -
connect (&Watcher1, SIGNAL(progressRangeChanged(int,int)),ui->progressBar, SLOT(setRange(int,int)));
connect (&Watcher1, SIGNAL(progressValueChanged(int,int)),ui->progressBar, SLOT(setValue(int)));
connect (&Watcher, SIGNAL(finished()), this, SLOT(slotProcessBar()));
void Rover::slotProcessBar()
{ui-> progressBar->setMaximum(1); ui->progressBar->reset();
}
-
@jagl said in QProgressBar:
connect (&Watcher1, SIGNAL(progressRangeChanged(int,int)),ui->progressBar, SLOT(setRange(int,int)));
connect (&Watcher1, SIGNAL(progressValueChanged(int,int)),ui->progressBar, SLOT(setValue(int)));
connect (&Watcher, SIGNAL(finished()), this, SLOT(slotProcessBar()));I am pretty sure that those connect do not work.
As far as I can see, Watcher1 is defined asQFutureWatcher<void> Watcher1;
and Watcher asQFutureWatcher<void>Watcher;
So there is no signal
progressRangeChanged(int,int)
available... so how should this work? -
@jagl
Aren't you asking just the same question/problem in https://forum.qt.io/topic/128560/set-qlabel-from-another-thread/ ?As we asked you there, if you would please take the time to change over to the New Signal Slot Syntax you would save us & yourself a lot of time on what looks like incorrect
connect()
s. -
@jagl said in QProgressBar:
thank you for your reply but why she work ?
This do NOT work!
I know that C++ is not a language which is easy to learn, but it is mandatory to learn it before trying to create application with Qt.
It is also strongly recommended to read documentation.
It is Okay not to understand all the stuff. In this case you can ask what you do not understand.Do you have read
QFutureWatcher
documentation?
https://doc.qt.io/qt-5/qfuturewatcher.html#detailsQFutureWatcher
is a template class to simplifyQFuture
monitoring.
So you can be informed when the QFuture is finished.