[Solved] PushButton Focus problem in a non-linear Wizard
-
Hi,
Ok, if I inderstood well, that is what you mean:
WPIni.h
@
private:
QPushButton *b1;
QPushButton *b2;
QPushButton b3;
QButtonGroup BGroup;
@WPIni.cpp
@WPInicial::WPInicial(QWidget *parent) :
BasePage(parent),
b1(new QPushButton),
b2(new QPushButton),
b3(new QPushButton),
BGroup(new QButtonGroup)
{
BGroup->addButton(b1,1);
BGroup->addButton(b2,2);
BGroup->addButton(b3,3);
[...]
}int WPIni::nextId() const
{
return this->BGroup->checkedId();
}
@If that is, the nextId always returns -1 and its like if it were the last page.
Thank you!
//------------------------------------------------//
Edited: I also tried putting
@
setFocusProxy(b1);
setFocusPolicy(Qt::TabFocus);
@ -
Did you make the buttons checkable ? Check one by default ?
-
Hi, now when you start the program you can see 3 big buttons (b1, b2, b3) and then the wizard's buttons (back, next, cancel). This buttons are grey but if the tabfocus is on them, they became blue, so when the app start, b1 is blue and if you press Tab, b1 becames grey and b2 blue.
Now, if I set the setCheckable() property to true to b1, b2 and b3, then when the app starts b1 is blue but if you Tab, you go directly to Fnish/Next button and you can't reach buttons b2 or b3.
I put next / finish because in that case next button becames finish button cause it detects that pae as the last one cause nextId() still returns -1)
Maybe the problem is that I'm doing a different thing than what I need really, I don't know...
My intention is:
- App starts with b1 in blue. [Now you can do p.e one of this 2 options]
- If you press Enter you go to the next page (not to next button) which is WP1.
- If you press Tab, b1 becames grey and b2 blue (it already does that now), and then if you press Enter you go to WP2.
I have another question... It's there any run loop? I mean, the tipically loop that is called every second or elapsedtime as the oen used in games to run the update and render loops... So as I know the code into the loop is being read every sec I can do something like:
@
if (Keypressed== Enter) then //if in any moment enter is pressed:
look wthich button has the focus
depending the button go to the WizardPage wanted.
endif
@It's an other option to do what I need maybe... It's a posssibility I just thought 'cause I need this to work and it doesn't T_T hehe
P.D: ischecked and has focus are diferents. I need that focus leads over check, to pick the button with the tab
-
You can use setTabOrder to setup which widget gets the focus after the current when pressing tab. And then the space key to check the button which the user select.
However a focused widget doesn't really tell the user that he just choose something. Either he should have a visual feedback like the one QRadioButton proposes or an exclusive checkable button group.
The event loop is already running.
-
Yes, I have already the visual effect becasue as I said, when u tab, the buttons became blue but what I don't know is how to know which is selected because hasFocus() returns( -1), BGroup->checkedId() returns (-1) and so on... -.-''
I've solved something but now I have 2 main problems:
-
If I press P I go to the next page. That is correct. But if I press Enter, nothing happens O.o Does anyone know why??? I want it to function with Enter key (And the same with TAB Key)
-
The other problem its the same I already had. nextId() ALWAS return - 1; (Visually with tab u see the change of the focus but it seems that for the program there is no button selected)
@
void WPIni::keyPressEvent(QKeyEvent *event) // definition
{
event->accept();switch(event->key())
{
case Qt::Key_Enter:
wizard()->next();
break;
case Qt::key_P:
wizard()->next();
break;
}
@
@
int WPIni::nextId() const
{
return this->BGroup->checkedId();
}
@Can I access to that event loop? So I can call a function inside him? I can't see were it is...
[EDITED: I saw that http://qt-project.org/doc/qt-4.8/focus.html but I don't see how to implement the filter, and still have the problem htat the tab and enter keys seems to not be recognized in the switch(event- > key) ]
-
-
Ok, I solved the filter and tab problem or at least it seems to.
But I have the same problem still... (I will explain it agian to make it as clear as possible because I don't really know what to do with that and I need a solution T_T)
I have this stylesheet on buttons that make them blue with white letters when tab focus its on them or when u click them
@
setStyleSheet("QPushButton{background-color:#d5d5d5; font: 20pt; font-weight: bold; } QPushButton:focus{background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d5d5d5, stop: 1 #8888a8); color: white;}");
@The thing is that is u click them or u use tab, their color change as it has to.
Example:
You are on b1 which is blue (b2 and b3 are grey).
You tab.
B1 becames grey, b2 blue and b3 stays grey.
you tab or you click b3.
b1 is grey, b2 is grey, b3 is blue.Well... If the program know who has to be blue... WHY CAN't I KNOW which button is?!!!!
-
Because the focus changed before nextId is called e.g. the Next button got it.
If you really want to work only with the focus, subclass QPushButton, emit a signal when focusIn is called then in your QWizardPage, catch that signal and update the next id value based on the sender of that signal.
-
I didn't know about that FocusIn/Out functions.
I think I will need a middle class (BaseButton) to reimplement that functions and emit the signal I am instered to?
What I have now is a really big mess on my mind -.-'' (I'm sorry but I'm new with Qt and all that at once exceeds me and the more things I try that I see here or in other post, the worst that works....) So I'll apreciate a lot if you can expecify that a little bit more or tell me what I am making wrong or what shold I put down and where:
My structure:
- class BaseWizard : public QWizard
- class BasePage : public QWizardPage -> All WizardPages inherite from that
- class BaseButton : public QPushButton -> New class. The QPushButton will inheritance from it to get when they are on focus
- class WPInicial : public BasePage -> WP initial that will see the user.The 3 buttons that it have have to redirect to WP1, WP2, y WP3.
BaseButton.cpp:
@
void BaseButton::focusInEvent(QFocusEvent *e)
{
if (e->reason() == Qt::TabFocusReason)
{
QPushButton::focusInEvent(e);
emit(focussed(true));
}
}
void BaseButton::focusOutEvent(QFocusEvent *e)
{
if (e->reason() == Qt::TabFocusReason)
{
QPushButton::focusOutEvent(e);
emit(focussed(false));
}
}
void BaseButton::setFocusb1(bool value)
{
if (value)
setFocus();
}
@BaseButton.h
@
class BaseButton : public QPushButton
{
Q_OBJECT
public:
BaseButton(QWidget *parent = 0);
~BaseButton();signals:
void focussed(bool hasFocus);
private slots:
void setFocusb1(bool value);public:
virtual void focusInEvent(QFocusEvent *e);
virtual void focusOutEvent(QFocusEvent *e);
};
@WPInicial.h (The buttons declaration now with basebutton)
@
BaseButton *_b1;
BaseButton *_b2;
BaseButton *_b3;
@
WPInicial.cpp
@
In the constructor:
_b1->installEventFilter(this);
_b2->installEventFilter(this);
_b3->installEventFilter(this);connect (_b1, SIGNAL(focussed(bool)),_b1, SLOT(setFocusb1(bool))); connect (_b2, SIGNAL(focussed(bool)),_b2, SLOT(setFocusb1(bool))); connect (_b3, SIGNAL(focussed(bool)),_b3, SLOT(setFocusb1(bool)));
@
If you think that I dont need BaseButton to get the focus then tell me so I can delete it.
Any help to fix that mess and be able to get the focus of a button will be very apreciated :) Meanwhile I'll continue with that mess...
Thank you so much
-
Let's simplify things a bit:
@
BaseButton.cpp:
void BaseButton::focusInEvent(QFocusEvent *e)
{
if (e->reason() == Qt::TabFocusReason)
{
emit focussed();
}
QPushButton::focusInEvent(e);
}BaseButton.h
class BaseButton : public QPushButton
{
Q_OBJECT
public:
BaseButton(QWidget *parent = 0);
~BaseButton();signals:
void focussed();protected:
virtual void focusInEvent(QFocusEvent *e);
};
WPInicial.h (The buttons declaration now with basebutton)
BaseButton *_b1;
BaseButton *_b2;
BaseButton *_b3;
QSignalMapper _mapper;
int _nextId;
WPInicial.cpp
In the constructor:
_mapper.setMapping(_b1, 0);
_mapper.setMapping(_b2, 1);
_mapper.setMapping(_b3, 2);
connect (_b1, SIGNAL(focussed()),&mapper, SLOT(map()));
connect (_b2, SIGNAL(focussed()),&mapper, SLOT(map()));
connect (_b3, SIGNAL(focussed()),&mapper, SLOT(map()));
connect(&_mapper, SIGNAL(mapped(int)), SLOT(buttonFocussed(int)));void WPInicial::buttonFoccussed(int nextId)
{
_nextId = nextId;
}
@[edit: Corrected typos]
-
Hi SGaist, thank you for all your help and for taking the time to write it for me :) This have became an alleviation for me really big.
I have made those changes to run it:
(note: I'm using Qt5)WPinicial.h
@public slots:
void buttonFoccussed(int nextId);@WPInicial.cpp
@ _mapper.setMapping(_b1, 0); //the compiler said addMapping didnt exists.
_mapper.setMapping(_b2, 1);
_mapper.setMapping(_b3, 2);@And then I have had to do that:
@int WPInicial::nextId() const
{
if (_b1->hasFocus())
return BaseWizard::Page1;
else if (_b2->hasFocus())
return BaseWizard::Page2;
else if (_b3->hasFocus())
return BaseWizard::Page3;
}@Page1,2,3 .... its the name of every WizarPage I gave in the enum.
I had to make that because your code never goes to WPInicial::buttonFoccussed(int nexId) function so _nextId never gets the right number...
With the override of nextId() I have a solution for my problem but now I'm wondering why does your code never go to buttonFocussed ??? I'm trying to understand how Qt's work with the signals and your code sound totally logic for me...(Note: I changed buttonFoccussed to buttonFocussed so that isn't the problem)
-
Because my emit line had a typo and a mix between QSignalMapper and QDataWidgetMapper…
You can replace 1,2,3 with BaseWizard::Page1 and friends so you only need to return _nextId
-
Ahh!! Ok, I understood it like internals idof the function even when I saw the Class reference -.-''
Thank you so much!