[Solved] How to access progressBar from a QWizardPage subclass
-
Hi folks:
I've a QWizard implementation, I mean a QWizard subclass and some QWizardPage subclasses. Everything is almost working fine, I know how to disable the next button through the isComplete function and all that kind of things. Lets say too that I've done all this using the QtCreator designer.
...so far so good
I got stuck when I'm trying to access to a progress bar that I placed at one of my three pages, therefore I can't update the progress bar. I'm doing this from the page itself, specifically from a custom function that I call from initializePage(), using QTimer::singleShot.
...trying to be more clear, I want to do something like this:
@
ui->progressBar->setValue(myValue);
@...but from the subclass of QWizardPage.
Thanks in advance.
-
This custom function of yours is a member of the QWizardPage subclass for that particular page? And you've used Qt Creator to create that subclass?
-
Yes, the function is a member of my QWizardPage subclass. I made the complete design, the wizard window and their pages, using the QtCreator design tool. After that, I created a QWizard subclass and a QWizardPage subclass for each page, to be able to handle things like hiding the Next button and so on. In one of this QWizardPage subclasses is where I created the custom function we are talking about and from this function is where I'm trying to access to the progressBar that I put in this page using the designer. After this I've promoted all subclasses to their equivalent widgets on the design.
Thanks for help.
-
I've been trying to solve this, one of the ideas that occurred to me was the following:
1 - Create a static function in my QWizard subclass:
@void MyQWizard::updateProgressBar(const int value) {
ui->progressBar->setValue(value);
}@
...remember that the only place where I can access the progressBar is from the QWizard subclass.
2 -Update the progressBar from my QWizardPage subclass:
@MyQWizard::updateProgressBar(value);@
...but it doesn't work. QtCreator give me an error, it said that I've committed a violation using "ui->progressBar->setValue(value);" from a static function.
...so I'm stuck again!!!
Thanks for help.
-
What error do you get, exactly, when you try to call
@ui->progressBar->setValue(value);@
from a member function (you certainly can't access it from a static function if it's a member variable!). -
Here is the error that I got when I try to call:
@
ui->progressBar->setValue(value);
@...from a static function.
The error output:
In static member function 'static void MyQWizard::updateProgressBar(int)':
error: invalid use of member 'MyQWizard::ui' in static member function...This error points to the line 42 of my code which have the follow declaration:
@
private:
Ui::CreateRepoWizard *ui;
@...included "private:" for clarity.
Thanks for help.
-
You cannot access a member variable from a static function: what error do you get when you try to do that from a member function?
-
In the example that I wrote above you can see that the function:
myqwizard.cpp:
@
MyQWizard::MyQWizard(QWidget *parent) : QWizard(parent), ui(new Ui::CreateRepoWizard) {...
}
...
void MyQWizard::updateProgressBar(const int value) {
ui->progressBar->setValue(value);
}
...
@
...is a member of MyQWizard class and as I said, it was declared as a static function:
myqwizard.h:
@
public:
static void updateProgressBar(const int value);
@I need this function be static, to be able to access it from progressPage(a QWizardPage subclass) without creating a new object of MyQWizard :
progresspage.cpp:
@#include <myqwizard.h>
ProgressPage::ProgressPage(QWidget *parent) : QWizardPage(parent) {
...
}
...
MyQWizard::updateProgressBar(value);
...
@Creating this member function as non-static will allow me to update the progressBar without problems, but it implies to create a new object of MyQWizard too, which doesn't have any sense in this scenario. Because I will be using a new instance of MyQWizard rather than the current, therefore I will be updating a different progressBar, that it's not the one that the wizard window shows.
Anyway thanks for the correction.
-
There are a couple approaches you can use here: the first is to emit a signal in ProgressPage that indicates that it would like the progress bar updated, and connect to that in MyQWizard to do the update. A second approach is to get a pointer to MyQWizard from within ProgressPage (is MyQWizard a parent widget, perhaps?). I'd lean towards to first solution for encapsulation reasons, but either will work. Fundamentally, though, you must have an object to operate on: that's why you can't use a static function.
-
As I said, thanks for the correction. I already understood that I can't use a static function. My next step will be try your suggestion, thanks again.
-
Got it!!!
l used the signal-slot approach as you suggested and it worked at the first try. It was so easy that I feel ashamed right now, but well, I guess it's a matter of experience.
Thanks for your continuous help and support, Chris H.
-
What did you use for the signal to emit? Value changed is a signal that is emitted from the progress bar. It looks like from your posting that you wanted to call MyQWizard::updateProgressBar(value); and you said you used a signal-slot solution. I was hoping to see what you used as a solution scheme.
-
I don't have access to the original code right now, so I made an example for you to have an idea how I've solved this.
Note that I've promoted the object "ui->progressBarPage" to "ProgressPage".
Here is the code:
mywizard.h:
@#ifndef MYWIZARD_H
#define MYWIZARD_H#include <QWizard>
namespace Ui {
class MyWizard;
}
class MyWizard : public QWizard
{Q_OBJECT
public:
explicit MyWizard(QWidget *parent = 0); ~MyWizard();
public slots:
void updateProgressBar(const int value);
private:
Ui::MyWizard *ui;
};
#endif // MYWIZARD_H@
mywizard.cpp:
@#include "mywizard.h"
#include "ui_mywizard.h"MyWizard::MyWizard(QWidget *parent) : QWizard(parent), ui(new Ui::MyWizard)
{ui->setupUi(this); ui->progressBar->reset(); connect(ui->progressBarPage, SIGNAL(updateProgressValue(int)), this, SLOT(updateProgressBar(int)));
}// Constructor
MyWizard::~MyWizard()
{delete ui;
}// Destructor
void MyWizard::updateProgressBar(const int value)
{ui->progressBar->setValue(value);
}// Update ProgressBar@
progresspage.h:
@#ifndef PROGRESSPAGE_H
#define PROGRESSPAGE_H#include <QWizardPage>
#include <QTimer>class ProgressPage : public QWizardPage
{Q_OBJECT
public:
explicit ProgressPage(QWidget *parent = 0); void initializePage();
signals:
void updateProgressValue(const int value);
private slots:
void updateValue();
private:
QTimer *timer; int count;
};
#endif // PROGRESSPAGE_H@
progresspage.cpp:
@#include "progresspage.h"
ProgressPage::ProgressPage(QWidget *parent) : QWizardPage(parent)
{timer = new QTimer(this); count = 0; connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
}// Constructor
void ProgressPage::initializePage() {
timer->start(100);
}// initializePage
void ProgressPage::updateValue() {
if(count == 100) { timer->stop(); return; }// if count++; emit updateProgressValue(count);
}// updateValue@
Hope this can help you.
-
Absolutely helps. Thanks very much.
-
Glad to know it.