Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 4

Qt-interest Archive, July 2007
Passing key events to a child widget


Message 1 in thread

On my main widget I have a child QTreeWidget.  I've overridden
keyPressEvent() on the main widget to look for certain key presses.  I'd
like for an up or down arrow key press to go to the QTreeWidget, as it
is the only widget in my app where up/down makes sense.

Unfortunately, keyPressEvent() is a protected member function, so I
can't just do:

void myWidget::keyPressEvent ( QKeyEvent * event ) {
  if ( (event->key() == Qt::Key_Up) ||
       (event->key() == Qt::Key_Down) )
  {
    if (ui.tree)
	ui.tree->keyPressEvent(event);
  } else {
    QMainWindow::keyPressEvent(event);
  }
}

The only other thing I can see is that I could write my own function
making use of:
  QTreeWidget::scrollToItem()
  QTreeWidget::setCurrentItem()

Am I missing some easier way?
Sean

--
 [ signature omitted ] 

Message 2 in thread

On 7/19/07, Murphy, Sean M. <sean.murphy@xxxxxxxxxx> wrote:
>
> On my main widget I have a child QTreeWidget.  I've overridden
> keyPressEvent() on the main widget to look for certain key presses.  I'd
> like for an up or down arrow key press to go to the QTreeWidget, as it
> is the only widget in my app where up/down makes sense.


Here are a couple of possibilities:

1) Call QWidget::setFocusProxy(QWidget*) on your QMainWindow and pass it a
pointer to your QTreeWidget. This should forward all of your keypress
events, etc. to the QTreeWidget whenever your QMainWindow has focus.

2) Call QObject::installEventFilter(QObject*) on your QMainWindow and pass
it a pointer to your QTreeWidget. In your QTreeWidget, implement
QObject::eventFilter(QObject*, QEvent*). If you look at the documentation
for these methods, they have an example that does almost exactly what you
describe.

Hope that helps,
Tom

Message 3 in thread

Forwarding this back to the list since it was sent in private. 

-----Original Message-----
From: Bo Thorsen [mailto:bo@xxxxxxxxxxxxxxxxxxxxx] 
Sent: Thursday, July 19, 2007 12:21 PM
To: Murphy, Sean M.
Subject: Re: Passing key events to a child widget

Hi Sean,

Just call child->event(theKeyEvent). event() will send it to the proper
handler.

Bo.

Murphy, Sean M. skrev:
> On my main widget I have a child QTreeWidget.  I've overridden
> keyPressEvent() on the main widget to look for certain key presses.  
> I'd like for an up or down arrow key press to go to the QTreeWidget, 
> as it is the only widget in my app where up/down makes sense.
>
> Unfortunately, keyPressEvent() is a protected member function, so I 
> can't just do:
>
> void myWidget::keyPressEvent ( QKeyEvent * event ) {
>   if ( (event->key() == Qt::Key_Up) ||
>        (event->key() == Qt::Key_Down) )
>   {
>     if (ui.tree)
> 	ui.tree->keyPressEvent(event);
>   } else {
>     QMainWindow::keyPressEvent(event);
>   }
> }
>
> The only other thing I can see is that I could write my own function 
> making use of:
>   QTreeWidget::scrollToItem()
>   QTreeWidget::setCurrentItem()
>
> Am I missing some easier way?
> Sean
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
"unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>   

--
 [ signature omitted ] 

Message 4 in thread

When I try that, I get the error:

 error C2248: 'QTreeWidget::event' : cannot access protected member
declared in class 'QTreeWidget'

Using
  ui.treePlannedReqt->event(event);

So it looks like event() is also protected in QTreeWidget.

Sean

-----Original Message-----
From: Murphy, Sean M. [mailto:sean.murphy@xxxxxxxxxx] 
Sent: Thursday, July 19, 2007 1:28 PM
To: qt-interest@xxxxxxxxxxxxx
Subject: FW: Passing key events to a child widget

Forwarding this back to the list since it was sent in private. 

-----Original Message-----
From: Bo Thorsen [mailto:bo@xxxxxxxxxxxxxxxxxxxxx]
Sent: Thursday, July 19, 2007 12:21 PM
To: Murphy, Sean M.
Subject: Re: Passing key events to a child widget

Hi Sean,

Just call child->event(theKeyEvent). event() will send it to the proper
handler.

Bo.

Murphy, Sean M. skrev:
> On my main widget I have a child QTreeWidget.  I've overridden
> keyPressEvent() on the main widget to look for certain key presses.  
> I'd like for an up or down arrow key press to go to the QTreeWidget, 
> as it is the only widget in my app where up/down makes sense.
>
> Unfortunately, keyPressEvent() is a protected member function, so I 
> can't just do:
>
> void myWidget::keyPressEvent ( QKeyEvent * event ) {
>   if ( (event->key() == Qt::Key_Up) ||
>        (event->key() == Qt::Key_Down) )
>   {
>     if (ui.tree)
> 	ui.tree->keyPressEvent(event);
>   } else {
>     QMainWindow::keyPressEvent(event);
>   }
> }
>
> The only other thing I can see is that I could write my own function 
> making use of:
>   QTreeWidget::scrollToItem()
>   QTreeWidget::setCurrentItem()
>
> Am I missing some easier way?
> Sean
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
"unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>   

--
 [ signature omitted ] 

Message 5 in thread

Hi!


 >
 >  error C2248: 'QTreeWidget::event' : cannot access protected member
 > declared in class 'QTreeWidget'
 >
 > Using
 >   ui.treePlannedReqt->event(event);
 >
 > So it looks like event() is also protected in QTreeWidget.
 >

try:
QApplication::sendEvent(ui.treePlannedReqt, event);

Greetings

Niklas

--
 [ signature omitted ] 

Message 6 in thread

>  >  error C2248: 'QTreeWidget::event' : cannot access 
> protected member  > declared in class 'QTreeWidget'
>  >
>  > Using
>  >   ui.treePlannedReqt->event(event);
>  >
>  > So it looks like event() is also protected in QTreeWidget.
>  >
> 
> try:
> QApplication::sendEvent(ui.treePlannedReqt, event);

It looks like this works, although I'm now having problems where
apparently the default keyboard navigation for the QTreeWidget doesn't
do bounds checking, so when the user presses the up key at the top of
the list, or presses the down key at the bottom of the list, the
applications crashes.

So it looks like maybe I need to write my own functional layer that
checks to see if I'm at either end of the list.

Thanks for the suggestions!
Sean

--
 [ signature omitted ] 

Message 7 in thread

> > try:
> > QApplication::sendEvent(ui.treePlannedReqt, event);
> 
> It looks like this works, although I'm now having problems 
> where apparently the default keyboard navigation for the 
> QTreeWidget doesn't do bounds checking, so when the user 
> presses the up key at the top of the list, or presses the 
> down key at the bottom of the list, the applications crashes.

Here's a quick example that shows the problem I'm having.  I've gotten
it to crash on Qt 4.1.4 on Windows and 4.1.1 on Mac.  Can anyone try it
on newer versions of Qt to see if crashes there?

All I have to do to make it crash is launch the app, press either the up
or down arrow, at this point the first tree widget item labeled "Item 1"
gets highlighted.  Then either press the up arrow key again (so trying
to go up when you are already at the top of the list), or press down 3
times (so trying to go down when you are at the bottom) and I get it to
crash.

If you comment out my reimplementation of keyPressEvent(), get focus on
the QTreeWidget, and start using the arrow keys, it will properly check
the bounds and not crash.

Sean 

Attachment:

Attachment: treewidget_test.tar.gz
Description: treewidget_test.tar.gz


Message 8 in thread

Not sure if this will work, but you could try ignore() for the relevant
(up and down arrow) events in your main widget's keyPressEvent(). This
will propagate the event to the main widget's parent.

....or, as you seem to suggest below, rather than attempt to send the
event to the child, get the child to do what you want, i.e. change the
current item.

....and -- I'm not sure if this is appropriate -- but you could try one
of the QCoreApplication functions like sendEvent( QObject * receiver,
QEvent * event ).

Sam Dutton 




 





SAM DUTTON
SENIOR SITE DEVELOPER

200 GRAY'S INN ROAD
LONDON
WC1X 8XZ
UNITED KINGDOM
T +44 (0)20 7430 4496
F 
E SAM.DUTTON@xxxxxxxxx
WWW.ITN.CO.UK

-----Original Message-----

From: Murphy, Sean M. [mailto:sean.murphy@xxxxxxxxxx] 
Sent: Thursday 19 July 2007 17:17
To: qt-interest@xxxxxxxxxxxxx
Subject: Passing key events to a child widget

On my main widget I have a child QTreeWidget.  I've overridden
keyPressEvent() on the main widget to look for certain key presses.  I'd
like for an up or down arrow key press to go to the QTreeWidget, as it
is the only widget in my app where up/down makes sense.

Unfortunately, keyPressEvent() is a protected member function, so I
can't just do:

void myWidget::keyPressEvent ( QKeyEvent * event ) {
  if ( (event->key() == Qt::Key_Up) ||
       (event->key() == Qt::Key_Down) )
  {
    if (ui.tree)
	ui.tree->keyPressEvent(event);
  } else {
    QMainWindow::keyPressEvent(event);
  }
}

The only other thing I can see is that I could write my own function
making use of:
  QTreeWidget::scrollToItem()
  QTreeWidget::setCurrentItem()

Am I missing some easier way?
Sean

--
 [ signature omitted ] 

Message 9 in thread

> Not sure if this will work, but you could try ignore() for 
> the relevant (up and down arrow) events in your main widget's 
> keyPressEvent(). This will propagate the event to the main 
> widget's parent.

Wouldn't this do exactly the opposite of what I'm trying to do?  Maybe I
didn't explain clearly enough, right now my main widget (inherited from
QMainWindow) gets the keystroke event, and there is no parent.  I want a
specific child (in this case a QTreeWidget) of the main widget to get
all up/down arrow key events, regardless of whether or not the
QTreeWidget has focus.  So I don't want to let the event propagate up, I
want to intentionally force it down to a specific child.

> ....or, as you seem to suggest below, rather than attempt to 
> send the event to the child, get the child to do what you 
> want, i.e. change the current item.

I can certainly do this, it just seems like there should be an easier
way!
 
> ....and -- I'm not sure if this is appropriate -- but you 
> could try one of the QCoreApplication functions like 
> sendEvent( QObject * receiver, QEvent * event ).

And here it is!  This seems to be exactly what I'm looking for.

Sean

> 
> From: Murphy, Sean M. [mailto:sean.murphy@xxxxxxxxxx]
> Sent: Thursday 19 July 2007 17:17
> To: qt-interest@xxxxxxxxxxxxx
> Subject: Passing key events to a child widget
> 
> On my main widget I have a child QTreeWidget.  I've overridden
> keyPressEvent() on the main widget to look for certain key 
> presses.  I'd like for an up or down arrow key press to go to 
> the QTreeWidget, as it is the only widget in my app where 
> up/down makes sense.
> 
> Unfortunately, keyPressEvent() is a protected member 
> function, so I can't just do:
> 
> void myWidget::keyPressEvent ( QKeyEvent * event ) {
>   if ( (event->key() == Qt::Key_Up) ||
>        (event->key() == Qt::Key_Down) )
>   {
>     if (ui.tree)
> 	ui.tree->keyPressEvent(event);
>   } else {
>     QMainWindow::keyPressEvent(event);
>   }
> }
> 
> The only other thing I can see is that I could write my own 
> function making use of:
>   QTreeWidget::scrollToItem()
>   QTreeWidget::setCurrentItem()
> 
> Am I missing some easier way?
> Sean
> 
> --
> To unsubscribe - send a mail to 
> qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the 
> subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
> Please Note:
> 
>  
> 
> Any views or opinions are solely those of the author and do 
> not necessarily represent those of Independent Television 
> News Limited unless specifically stated. 
> This email and any files attached are confidential and 
> intended solely for the use of the individual or entity to 
> which they are addressed. 
> If you have received this email in error, please notify 
> postmaster@xxxxxxxxx 
> 
> Please note that to ensure regulatory compliance and for the 
> protection of our clients and business, we may monitor and 
> read messages sent to and from our systems.
> 
> Thank You.
> 
> --
> To unsubscribe - send a mail to 
> qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the 
> subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
> 
> 

--
 [ signature omitted ] 

Message 10 in thread

If I understand what you are trying to do, you may be able to get away with 
reposting the event with a different reciever using QApplication::postEvent()
http://doc.trolltech.com/4.3/qcoreapplication.html#postEvent
But I would use the sendEvent method as mentioned below.

Katrina Niolet

Le Thursday 19 July 2007 02:31:53 pm Murphy, Sean M., vous avez écrit :
> > Not sure if this will work, but you could try ignore() for
> > the relevant (up and down arrow) events in your main widget's
> > keyPressEvent(). This will propagate the event to the main
> > widget's parent.
>
> Wouldn't this do exactly the opposite of what I'm trying to do?  Maybe I
> didn't explain clearly enough, right now my main widget (inherited from
> QMainWindow) gets the keystroke event, and there is no parent.  I want a
> specific child (in this case a QTreeWidget) of the main widget to get
> all up/down arrow key events, regardless of whether or not the
> QTreeWidget has focus.  So I don't want to let the event propagate up, I
> want to intentionally force it down to a specific child.
>
> > ....or, as you seem to suggest below, rather than attempt to
> > send the event to the child, get the child to do what you
> > want, i.e. change the current item.
>
> I can certainly do this, it just seems like there should be an easier
> way!
>
> > ....and -- I'm not sure if this is appropriate -- but you
> > could try one of the QCoreApplication functions like
> > sendEvent( QObject * receiver, QEvent * event ).
>
> And here it is!  This seems to be exactly what I'm looking for.
>
> Sean
>
> > From: Murphy, Sean M. [mailto:sean.murphy@xxxxxxxxxx]
> > Sent: Thursday 19 July 2007 17:17
> > To: qt-interest@xxxxxxxxxxxxx
> > Subject: Passing key events to a child widget
> >
> > On my main widget I have a child QTreeWidget.  I've overridden
> > keyPressEvent() on the main widget to look for certain key
> > presses.  I'd like for an up or down arrow key press to go to
> > the QTreeWidget, as it is the only widget in my app where
> > up/down makes sense.
> >
> > Unfortunately, keyPressEvent() is a protected member
> > function, so I can't just do:
> >
> > void myWidget::keyPressEvent ( QKeyEvent * event ) {
> >   if ( (event->key() == Qt::Key_Up) ||
> >        (event->key() == Qt::Key_Down) )
> >   {
> >     if (ui.tree)
> > 	ui.tree->keyPressEvent(event);
> >   } else {
> >     QMainWindow::keyPressEvent(event);
> >   }
> > }
> >
> > The only other thing I can see is that I could write my own
> > function making use of:
> >   QTreeWidget::scrollToItem()
> >   QTreeWidget::setCurrentItem()
> >
> > Am I missing some easier way?
> > Sean
> >
> > --
> > To unsubscribe - send a mail to
> > qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the
> > subject or the body.
> > List archive and information: http://lists.trolltech.com/qt-interest/
> > Please Note:
> >
> >
> >
> > Any views or opinions are solely those of the author and do
> > not necessarily represent those of Independent Television
> > News Limited unless specifically stated.
> > This email and any files attached are confidential and
> > intended solely for the use of the individual or entity to
> > which they are addressed.
> > If you have received this email in error, please notify
> > postmaster@xxxxxxxxx
> >
> > Please note that to ensure regulatory compliance and for the
> > protection of our clients and business, we may monitor and
> > read messages sent to and from our systems.
> >
> > Thank You.
> >
> > --
> > To unsubscribe - send a mail to
> > qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the
> > subject or the body.
> > List archive and information: http://lists.trolltech.com/qt-interest/
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/


--
 [ signature omitted ]