progress bar not updating during iterations but updating once the process is completed?
-
I am doing some calibration Calculations. So I was taking some iterations as an argument and calibrating this many times as iterations and averaging it. I wanted to know the normalized current iteration to user in progressbar. So my plan is here to update progressbar with iteration number everytime.
So i tried to use SIGNALS and SLOTS(but got confused on doing it and didnt implement that properly) to update the progress bar. So Please look into this part!
I am also running calibration function in another thread so gui stays responsive since my calib function is somewhat calculation intensive.
But in my implementaion progress bar value is updating at the end of process but not at the every iteration .
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); init_gui(); init_cam(); getcamDescription(); // In first argument of my connect i need to write sender but what will be the sender here?? // should it be calib function? Pretty much confused here connect(this,SIGNAL(valueChanged(int)),ui->progressBar,SLOT(setValue(int))); } Widget::~Widget() { delete ui; delete dt; } void Widget::on_pushButton_clicked() { if(ui->progressBar->value() != 0) { ui->progressBar->setValue(0); // implemented this bcoz otherwise progress value is fixed // for e.g if i press first time push button my progress bar reaches 100 percent at the end of the process // but if i press push button again it stays 100 in starting also so implemented this part } ui->plainTextEdit->clear(); // to clear previous messages once again push button is pressed iterations = ui->lineEdit_3->text().toInt(); ui->plainTextEdit->appendHtml("<div style='color: green;'> Process Started </div>"); // runs Calib function in another thread auto func = std::bind(&Widget::Calib,this,bodyidx,iterations); QThread* qthread = QThread::create(func); qthread->start(); } void Widget::setValue(int value) { if (value != m_value) { m_value = value; emit valueChanged(value); } } void Widget::Calib(int bodyidx,int iterations) { Eigen::Matrix4f rhom; Eigen::Matrix3f rot; Eigen::Matrix4f rhomInv; std::vector<Eigen::Quaternionf> quat(iterations); custom_bodytype body; float bodylocacc[3] = { 0, 0, 0 }; for(int ii=0;ii<iterations;ii++) { // some eigen caluclations } Eigen::Matrix4f A; A << 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; Eigen::Vector4f quadvec; for (int jj = 0;jj < iterations;jj++) { //ui->plainTextEdit->appendPlainText("Iteration :" + QString::number(jj)); int kk = normalize(ui->lineEdit_3->text().toInt(),jj+1); // if jj+1 is not used normalize will give 90% but it never shows it completed 100% //ui->progressBar->setValue(kk); setValue(kk); // some eigen calcs again } // scale matrix A = A/iterations; // Get the max eigenvalue int maxidx; float maxval; EigenSolver<Matrix4f> B(A); Eigen::Vector4cf eigenval; float eigenvalmag[4]; eigenval = B.eigenvalues(); for (int ii = 0;ii < 4;ii++) { // some calculatiosn } // again some calculations } int Widget::normalize(int iterations, int curriternum) { int min = 0; int max = iterations; float den = max-min; float num = curriternum - min; float normalized = num/den; int res = normalized * 100; return res; }
my header file is like this
#include <QString> #include <QDir> #include <QRegExp> #include <QThread> #include <sstream> #include <windows.h> #include <vector> #include <map> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void on_lineEdit_3_returnPressed(); void on_lineEdit_2_returnPressed(); void on_pushButton_clicked(); void setValue(int value); signals: void valueChanged(int newValue); private: Ui::Widget *ui; void init_gui(); void init_cam(); void Calib(int bodyidx,int iterations); int normalize(int iterations, int curriternum); int m_value; }; #endif // WIDGET_H
-
Only one thing: You must not access or try to modify widgets outside the main gui thread. So fix your code and use proper signals/slots instead.
-
@Christian-Ehrlicher You mean since i am updating my progress bar with iteration number inside calib function(which is running in another thread) so my progress bar update is not working as intended right? . Even If i run my calib function in the same thread it is giving me same kind of output!
I didnt change anything in SIGNAL and SLOT implementation. (It was the same as mentioned in one of the screenshots above.)
Please correct me if i am wrong!.
-
When you run your loop in the gui thread then the ui is blocked since you block the eventloop.
-
This post is deleted!
-
Move your heavy calculation into an own thread as shown in the documentation and the examples there.
-
@Christian-Ehrlicher Hi!, I didnt change anything in the code as mentioned in the question. This comment is rather to get some more clarity for myself. I think i moved my heavy calculation part into the different thread. But inside this new thread i have two for loops and inside my second loop i want to pass iteration number by normalizing it to 0-100 to progressbar. So I am still confused why it is happening like this. And as per what i found is Threads can run an event loop.
Sorry for being dumb :-( . The more i go to documenation and some questions in stack and qt forum it is making me more confuse :-). May be because i am beginner :-)
-
@aravmadd said in progress bar not updating during iterations but updating once the process is completed?:
So I am still confused why it is happening like this
Because you modify ui stuff from another thread which is not allowed. Use signals and slots as I already wrote 3 days ago.
-
@Christian-Ehrlicher Hi Thanks I am working on implementing it in worker class. I am trying to create worker class and do some intensive work there.
I have a small question here , how can i get information from ui into worker class? For example if i have some text in LineEdit i need to get this information in worker class.
-
@aravmadd said in progress bar not updating during iterations but updating once the process is completed?:
how can i get information from ui into worker class?
via signals/slots
-
@jsulm Thanks it took me some time to figure it out on correct implementation of signals and slots.
Now its working.
What i did was
I ran the heavy calculation function in another thread using QtConcurrent.
Then from the heavy function i emitted signal , with the emitted signal i defined one slot(in my widget.cpp) which updates my progress bar.
Here is how it looksconnect(this, &Widget::updateProgress, this, &Widget::onProgressValueChanged);
After this i connected signal and slot properly it worked fine.
Initially i thought it is not working because the update is too fast that i cannot see real update in progress bar, then i only updated at 25 percent and 50 percent and 75 and 100 percent to my progress bar. Then i can see the progress in progress bar.