PDA

View Full Version : How to hide all wizard buttons



roseicollis
12th February 2015, 12:43
Hi,

I have a wizard app with its wizardpages and in some of them, I want to hide ALL wizardbuttons.

My wizard is declared this way:


class BaseWizard : public QWizard

And I've tried this on the constructor:


BaseWizard::BaseWizard(QWidget *parent) :
QWizard(parent),
ui(new Ui::BaseWizard)
{

this->button(QWizard::NextButton)->setVisible(false);
this->button(QWizard::CancelButton)->setVisible(false);
this->button(QWizard::BackButton)->setVisible(false);
this->button(QWizard::FinishButton)->setVisible(false);
this->button(QWizard::CustomButton1)->setVisible(false);


And also with setEnabled(false) and with hide() and yes, Cancel, and CutomButton disappear BUT Next and Back always remain there. I tried to put it too in the initializepage() of the wizardpage but its the same.

Any idea of why do that buttons saty there? Or what am I doing wrong?

Thank you so much!

ChrisW67
12th February 2015, 19:59
Aside from the question of how you are supposed to navigate a wizard with no buttons... the Next button is controlled by the return value of nextId(). The Back button will likely be made visible if you navigated to this page from another.

roseicollis
13th February 2015, 08:11
how you are supposed to navigate a wizard with no buttons

Well in some pages I have my own buttons and as the interaction is full with keyboard that means that they user goes to the next page with Enter/Return key and back with backspace. So in that cases, wizard's buttons annoy more than anything cause they have no function and there is no reason to have something which has no use and can confuse the user.


he Next button is controlled by the return value of nextId()
Okey... so.... how can I 'not show that button' in a wizardpage?


The Back button will likely be made visible if you navigated to this page from another.
First it didn't work.. as I said I tried with all buttons and back and next always stays there -.-'' and second.... what about the first page?

Thank you!

d_stranz
13th February 2015, 16:06
So why don't you just live with the buttons and cause the Enter and Backspace keys to cause clicks on the Next and back buttons?

I agree with ChrisW67 - you are implementing a very weird QWizard. If you don't like the standard behaviour, then why not just emulate a QWizard with a set of pages in a custom QStackedWidget? You would have absolute control over which page is shown when without having to worry about all those pesky buttons.

wysota
14th February 2015, 15:53
Well in some pages I have my own buttons and as the interaction is full with keyboard that means that they user goes to the next page with Enter/Return key and back with backspace. So in that cases, wizard's buttons annoy more than anything cause they have no function and there is no reason to have something which has no use and can confuse the user.

So why are you using a wizard at all? Why not have a QStackedWidget with a bunch of pages?

roseicollis
16th February 2015, 12:20
So why don't you just live with the buttons and cause the Enter and Backspace keys to cause clicks on the Next and back buttons?

Well.. it would be so extrange that in some pages you have next and back button for no reason... I have already implemented the behaviour of enter but its ugly to have things on the screen for no reason and that if you focus them, they do nothing (because the focus would be on them and not in any option of the screen)


So why are you using a wizard at all? Why not have a QStackedWidget with a bunch of pages?
The reason for that is that a work mate told me to do it with wizard structure so I did it. I suppossed that it was the best option and moreover, I never saw before the class StackedWidget until u mentioned it O.o I'll try to go with the wizard 'cause I have to finish that and I have no time to try to change it into a QStackedWidget but I will consider that in the futur or later if I need it.

One question... if a QStackedWidget can have a lot of widgets and pages like the wizard... does that mean that I can use the same pages I have already on the wizardpage? I mean: Now I have a QWizard with a lot of QWizardPages... so could I have a QStackedWidget with a lot of QWizardPages? and so the change is just so little? Or would it be much more complicated?

Thank you !!

wysota
16th February 2015, 14:00
The wizard is implemented over QStackedWidget so basically yes, you can reuse your pages. Just remember wizard() will then return null.

roseicollis
16th February 2015, 16:46
Just remember wizard() will then return null.

What do you mean with that?

Another thing: On the QWizard constructor I have this:

this->button(QWizard::NextButton)->setFocusPolicy(Qt::TabFocus);

I'm trying to set focus policy Qt::NoFocus on that wizardpages were I don't want to have that buttons (so at least user will see them but won't reach them with tab), on its constructors or initializePage() but the program ignores me. It always do what I put on the QWizard class constructor.

For example:

QWizard constructor: this->button(QWizard::NextButton)->setFocusPolicy(Qt::TabFocus);
QWizardPage 1 where I don't want the buttons: wizard()->button(QWizard::NextButton)->setFocusPolicy(Qt::NoFocus);
QWizardPage 2 where I want the buttons again: wizard()->button(QWizard::NextButton)->setFocusPolicy(Qt::TabFocus);

result: on wp 1 and wp 2 its like setFocusPolicy(Qt::TabFocus);

So... can't I switch between focuspolicies?

Thank you!

wysota
16th February 2015, 17:42
What do you mean with that?
I mean QWizardPage::wizard() is not going to return a valid wizard pointer if you are not going to have a wizard but a stacked widget instead.

ChrisW67
16th February 2015, 19:58
I'm trying to set focus policy Qt::NoFocus on that wizardpages were I don't want to have that buttons (so at least user will see them but won't reach them with tab), on its constructors or initializePage() but the program ignores me. It always do what I put on the QWizard class constructor.

It is evident that you do not want the features of QWizard so stop tryng to bend it to your will and simply reimplement your multi-page dialog using QStackedWidget and whatever other logic you want. Switching approach is less effort than you have put into this thread.

d_stranz
17th February 2015, 18:02
It's funny how some of us (and I am guilty as well) are so resistant to throwing out ineffective code that "sort of works but not really", when it is obvious (even while I am being resistant) that just biting the bullet and throwing it out would result in something that is so much cleaner and maintainable. Pack rat mentality, I suppose.

wysota
17th February 2015, 21:43
I never hestitate to throw away everything I've got and start from scratch. Unfortunately (at least for me) my workmates rarely share my point of view. How do you tell your boss that the thing you've been working on for the last two weeks should be trashed. And how do you explain you will just need two days to rewrite it? "So what have you been doing during those two weeks?"

d_stranz
18th February 2015, 04:21
I perpetually make the mistake of working from the inside out, starting with data representation and algorithms, and then developing the GUI later. When the boss comes by and says, "Show me the program", and I say, "There isn't one yet", the reply is, "Well, then what have you been doing?" But if I do it from the outside in, I end up with so many wires dangling from the GUI that invariably some of them don't get hooked up. The boss is happy though - seeing the knobs and the blinking lights gives the impression that I'm actually working.

roseicollis
18th February 2015, 10:47
Yes,

Basically this is my main problem :P I don't have more time to change so I'll keep it that way because its fine for the boss(not for me because I don't like to have buttons with no function on them but...) and if I have to change it later, I'll see what I do.

Y tried to put a stackwidget in mainwindow and throw mainwindow on main.cpp instead of wizard, and in this stackedwidget, put my first 3 wizardpages and it worked but not so fine... I threw my wizard like:


//main.cpp
MyWizard mw;
mw.setFixedSize(800,700);
mw.showMaximized();


The setfixedSize is for setting the developing window to the same as the final screen (it will go to a device with that resolution). So when I put it all in the stackedwidget in mainwindow and throw:



//main.cpp
MainWindow mm;
mm.setFixedSize(800,700);
mm.showMaximized();


Then the screen size is the fixed one but the widgets inside have another. The wizardpage1 for example have a VBoxLayout where I add all the items and it worked well on the wizard but it seems that it doesn't work with the stackedwidget so not having time to see what happens I'll let the Wizard structure for the moment.

wysota
18th February 2015, 11:12
Then the screen size is the fixed one but the widgets inside have another. The wizardpage1 for example have a VBoxLayout where I add all the items and it worked well on the wizard but it seems that it doesn't work with the stackedwidget so not having time to see what happens I'll let the Wizard structure for the moment.

Most likely you didn't set a layout somewhere. And use QStackedWidget instead of QMainWindow, you don't need one.

roseicollis
19th February 2015, 11:09
Most likely you didn't set a layout somewhere. And use QStackedWidget instead of QMainWindow, you don't need one.

Ok, I created a new Qt class on the project which is

class StackedWidget : public QStackedWidget
and I copied the same code I had in Mainwindow to its constructor, so I have:


StackedWidget::StackedWidget(QWidget *parent) :
QStackedWidget(parent),
ui(new Ui::StackedWidget)
{
ui->setupUi(this);

QWidget* centralWidget = new QWidget();
QComboBox *m_pComboBox = new QComboBox();

addWidget(new WP1);
addWidget(new QPushButton("Button 3"));
addWidget(new QPushButton("Button 2"));
setFixedSize(480,300);

m_pComboBox->addItem("Page 1");
m_pComboBox->addItem("Page 2");
m_pComboBox->addItem("Page 3");

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(m_pComboBox);

setWindowTitle("QStackedWidget Change CurrentIndex");
centralWidget->setLayout(layout);
setFixedSize(500,350);

connect(m_pComboBox,SIGNAL(activated(int)),this,SL OT(setCurrentIndex(int)));
}
But it shows nothings more than an empty window

And in main.cpp :



StackedWidget st;
st.setFixedSize(960,600);
st.show();

wysota
19th February 2015, 11:30
What sense does it make to setup a UI file on a stacked widget? You are treating it like a common widget and not as a stacked widget. Stop blindly copying code in hope it will work :(

roseicollis
19th February 2015, 11:35
Ohhhhhhhhhh shit... forgot to comment that line... -.-''

The line its created by Qt when I create the class and I always comment it, but this time I didn't see it... my fault... I was blind thinking about the layouts and didn't see that.

Thank you!

Edit: One more thing: In wp1 I have 2 buttons, do you know why do they appear at the bottom of the page and not at the top? I mean.. now is like if there were gravity and buttons go as down as they can while before, with QWizard they were as 'up' as they can.

d_stranz
24th February 2015, 00:29
The code you have written for your StackedWidget class makes no sense at all.

A stacked widget is just an empty container for holding a collection of other widgets. The collection is like deck of cards, and only one card can be visible at a time. The code you wrote adds three cards to the deck: the first one of type WP1, the next two of type QPushButton.

Then you do something weird with a combo box in a layout and you set that as a "central widget", whatever that is. Is it a new widget in the stack?

If I can try to look inside your mind, it appears that what you might want to do is to have a combo box that lets you choose which widget in the stack you want to be visible. In that case, you don't want that combo box to be in the stack of widgets at all, you want it to be external to it.

So if that's what you want, then create a new class, derived from plain old vanilla QWidget, add a QVBoxLayout to it, put the combobox on top and a plain old vanilla QStackedWidget in the bottom. In the constructor for this widget, fill in your combo box, create the widgets that will serve as the cards in your stack, and choose which one appears first.

If you want to keep the design flexible, if you have widgets in the stack that need to control which page is shown next (click a button on page 1 that causes page 3 to be shown), then expose that click to the top level widget using a custom signal, and let the top level widget tell the stack which page to show next. If you push this logic down into the individual pages (as you appeared to have been doing), then you end up with a rat's nest of interdependent code.

Signals and slots help you modularize things and make it so that the only widgets that need to know the details of what's going on are the ones in charge. All the little low-level widgets just do their thing and tell the guys in charge (via signals) that something has happened that they might want to pay attention to.

Look a QPushButton - does it care what widget it is inside of? No. It's whole job is to display its label and icon and to let whoever cares know when someone has clicked it. Your page widgets should act the same way.

roseicollis
26th February 2015, 12:46
Thanks d_stranz,

That example was so clear :)