For some GUI application I use QMainWindow with different controls on it: QGraphicsScene + QGraphicsView , QPushButtons, QWidget. Inside QGraphicsScene located a lot of different items type:
QGraphicsPolygonItem
QGraphicsTextItem
QGraphicsRectItem
But for me is most im开发者_Go百科portant is Polygon item, this item has those flags:
setFlag(QGraphicsItem::ItemIsFocusable, true);
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
I can select every item by mouse, but I need to change focus for those items by Tab. How is it possible ?
SetTabOrder worked only with QGraphicsObjects. I tried to solve this problem with QGraphicsView::focusNextPrevChild redefining
bool MyGraphicsView::focusNextPrevChild( bool next )
{
QGraphicsPolygonItem *target;
QGraphicsPolygonItem *current;
if( scene()->focusItem() )
{
target = qgraphicsitem_cast<QGraphicsPolygonItem*>( scene()->focusItem() );
bool is_focus_next=false;
foreach( QGraphicsItem *item, scene()->items() )
{
current = qgraphicsitem_cast<QGraphicsPolygonItem*>( item );
// set focus for next before selected
if( current && is_focus_next )
{
item->setFocus( Qt::MouseFocusReason );
// item->setSelected( true );
is_focus_next = false;
break;
}
// searching for selected item
if( current && current == target )
{
is_focus_next = true;
}
}
}
}
But only first Tab worked, When I pressed Tab again focus has moved to other QWidget outside the QGraphicsView control. Please, could you help me with Tab order focus for QGraphicsItem.
Thank you
EDIT: The final version, thanks to Steffen.
bool MyGraphicsView::focusNextPrevChild( bool next )
{
QGraphicsPolygonItem *target;
QGraphicsPolygonItem *current;
if( scene()->focusItem() )
{
target = qgraphicsitem_cast<QGraphicsPolygonItem*>( scene()->focusItem() );
bool is_focus_next=false;
foreach( QGraphicsItem *item, scene()->items() )
{
current = qgraphicsitem_cast<QGraphicsPolygonItem*>( item );
// set focus for next before selected
if( current && is_focus_next )
{
item->setFocus( Qt::MouseFocusReason );
return true;
}
// searching for selected item
if( current && current == target )
{
is_focus_next = true;
}
}
}
return QGraphicsView::focusNextPrevChild(next);
}
You should return true
to indicate that you actually found a widget. As you have no return statement at all at the moment, the behaviour is undefined. You can also add some logic to return false
on the last element to allow the user to leave your QGraphicsView
again.
See also the documentation for QWidget::focusNextPrevChild().
精彩评论