Qt-interest Archive, January 2007
How can a QWidget get notified when it gains focus?
Message 1 in thread
Hi,
MyDialog is derived from QWidget/QDialog.
I wish to get notified when it receives/looses focus.
I tried:
void setFocusPolicy ( Qt::FocusPolicy policy )
and overwrite
void QWidget::focusInEvent ( QFocusEvent * event )
But it does not work.
I also tried focusChanged() signal:
connect(static_cast<QApplication *>(QCoreApplication::instance()),
SIGNAL(focusChanged (QWidget *, QWidget *)),
this, SLOT(myFocusChangedSlot(QWidget *, QWidget *)));
Two problems with this practice:
1) Too frequently myFocusChangedSlot() get called, even MyDialog, a
modeless dialog, is NOT shown.
2) I tested a filter, unfortunately, it does not work.
void MyDialog::focusChanged( QWidget * old, QWidget * now )
{
if(now == this) // filter does not work!?
{
}
}
Even worse, I did two iterations by
this->parentWidget();
and
now->parentWidget();
and found NO relation between "this" and "now" in runtime focus change.
Ridiculous, isn’t it?
Does anyone have experience how to receive a notify message/event/signal
when the a target widget receives/loose focus?
Thanks in advance.
Lingfa
--
[ signature omitted ]
Message 2 in thread
When I had a similar problem I installed an eventFilter on my widgets.
bool xxxx::eventFilter(QObject *object, QEvent *event){
....
}
and in constructor:
installEventFilter(this);
Guido
On Mon, Jan 29, 2007 at 12:28:56PM -0500, lingfa wrote:
> Hi,
>
> MyDialog is derived from QWidget/QDialog.
> I wish to get notified when it receives/looses focus.
>
> I tried:
> void setFocusPolicy ( Qt::FocusPolicy policy )
> and overwrite
> void QWidget::focusInEvent ( QFocusEvent * event )
> But it does not work.
>
>
...
--
[ signature omitted ]
Message 3 in thread
lingfa wrote:
> MyDialog is derived from QWidget/QDialog.
> I wish to get notified when it receives/looses focus.
>
> I tried:
> void setFocusPolicy ( Qt::FocusPolicy policy )
> and overwrite
> void QWidget::focusInEvent ( QFocusEvent * event )
> But it does not work.
I have to say that this also confused me, initially, since I believe you
could do this in Qt 3 for top-level widgets and dialogs.
Apparently, windows (top-level widgets) do not receive focus change events,
but child widgets do. Since a dialog is a window, you need to implement
QWidget::changeEvent() and check for QEvent::ActivationChange events:
http://doc.trolltech.com/4.2/qwidget.html#changeEvent
Good luck!
David
--
[ signature omitted ]
Message 4 in thread
lingfa schrieb:
> Hi,
>
> MyDialog is derived from QWidget/QDialog.
> I wish to get notified when it receives/looses focus.
Hmmm, I'm not sure: I don't think a QDialog ever gets focus, but I might
completely be wrong! A QLineEdit, a QSpinBox or a QTextEdit (or any
other *input* widget) gets focus, but not a simple dialog (which after
all is just a "frame" to hold the input widgets together).
But you might want to have a look at
QWidget::mouseMoveEvent()
after you have enabled mouse tracking with
QWidget::setMouseTracking (bool enable)
> I tried:
> void setFocusPolicy ( Qt::FocusPolicy policy )
With what parameters *exactly* did you try it? I would expect the
following should work (in case QDialogs also get focus):
Qt::StrongFocus
(or even Qt::WheelFocus)
> and overwrite
> void QWidget::focusInEvent ( QFocusEvent * event )
> But it does not work.
How does it not work? I assume you mean your focusInEvent is never
called when you click into the dialog, right?
Cheers, Oliver
--
[ signature omitted ]
Message 5 in thread
On Jan 30, 2007, at 11:49 AM, Till Oliver Knoll wrote:
> lingfa schrieb:
>> Hi,
>>
>> MyDialog is derived from QWidget/QDialog.
>> I wish to get notified when it receives/looses focus.
>
> Hmmm, I'm not sure: I don't think a QDialog ever gets focus, but I
> might
> completely be wrong! A QLineEdit, a QSpinBox or a QTextEdit (or any
> other *input* widget) gets focus, but not a simple dialog (which after
> all is just a "frame" to hold the input widgets together).
Take a look at QWidget::changeEvent(). I think lingfa is interested
in QEvent::ActivationChange.
Brad
--
[ signature omitted ]
Message 6 in thread
Brad Howes wrote:
> On Jan 30, 2007, at 11:49 AM, Till Oliver Knoll wrote:
>
>> lingfa schrieb:
>>
>>> Hi,
>>>
>>> MyDialog is derived from QWidget/QDialog.
>>> I wish to get notified when it receives/looses focus.
>>
>>
>> Hmmm, I'm not sure: I don't think a QDialog ever gets focus, but I might
>> completely be wrong! A QLineEdit, a QSpinBox or a QTextEdit (or any
>> other *input* widget) gets focus, but not a simple dialog (which after
>> all is just a "frame" to hold the input widgets together).
>
>
> Take a look at QWidget::changeEvent(). I think lingfa is interested in
> QEvent::ActivationChange.
Thanks Brad,
This is a good function. I like it.
Let’s say I have two instances of MyDialog (modeless).
At the moment I show one, I want this one to be actived:
ptr->show();
ptr->activateWindow(); // without this, show() doesn't make a modeless
dialog shows up.
I found activateWindow() does trigger the call you mentioned:
void MyDialog::changeEvent(QEvent * event)
{
// I reach here. Wonderful !
}
In parallel, focusInEvent ()
void MyDialog::focusInEvent ( QFocusEvent * event )
{
// I never reach here. Awful !
}
My guess is:
1) The event is consumed by one of its component widgets. It never
reached "this" frame/dialog!
2) This frame/dialog looks like a parentWidget() of its components, but
actually not, at least, it is not necessarily to be.
Switch focus from one dialog to the other doesn’t trigger
changeEvent()/focusInEvent()
Question is still open. Help please.
Thanks my Qt friends,
Lingfa
--
[ signature omitted ]
Message 7 in thread
On Jan 30, 2007, at 4:20 PM, lingfa wrote:
> Brad Howes wrote:
>> Take a look at QWidget::changeEvent(). I think lingfa is
>> interested in QEvent::ActivationChange.
>
> Switch focus from one dialog to the other doesn’t trigger
> changeEvent()/focusInEvent()
> Question is still open. Help please.
Focus events affect widgets which can accept keyboard input. When
your dialog gets its change event stating that it is active, you
could force one of your dialog widgets to acquire focus. Or, you
could enable focus for your QDialog with setFocusPolicy() -- the
default is Qt::NoFocus so your QDialog will never get focus events
(if it does not change the default value). Also, there is
QApplication::focusChanged() signal which you can listen to for *all*
focus changes, then compare pointer values to see if a widget on your
QDialog has received focus.
Brad
--
[ signature omitted ]
Message 8 in thread
Brad Howes wrote:
> On Jan 30, 2007, at 4:20 PM, lingfa wrote:
>
>> Brad Howes wrote:
>>
>>> Take a look at QWidget::changeEvent(). I think lingfa is interested
>>> in QEvent::ActivationChange.
>>
>>
>> Switch focus from one dialog to the other doesn’t trigger
>> changeEvent()/focusInEvent()
>> Question is still open. Help please.
>
>
> Focus events affect widgets which can accept keyboard input. When your
> dialog gets its change event stating that it is active, you could
> force one of your dialog widgets to acquire focus. Or, you could
> enable focus for your QDialog with setFocusPolicy() -- the default is
> Qt::NoFocus so your QDialog will never get focus events (if it does
> not change the default value).
I did:
this->setFocusPolicy(Qt::StrongFocus);
in MyDialog’s constructor or/and
void MyDialog::changeEvent(QEvent * event)
{
this->setFocusPolicy(Qt::StrongFocus);
}
But focusInEvent() has never been reached, because one of its component
widget consume the event.
> Also, there is QApplication::focusChanged() signal which you can
> listen to for *all* focus changes, then compare pointer values to see
> if a widget on your QDialog has received focus.
I hope so, but failed.
void SliceGeneratorTab::focusChanged( QWidget * old, QWidget * now )
{
QWidget* p = now;
while(p)
{
if(p == this || p == this->tab)
stdafx::showString("Catch you."); // but never!
p = p->parentWidget();
}
}
Thanks,
Lingfa
--
[ signature omitted ]